【Java核心技术_二十七】Java 自定义注解+Spring AOP 实现统一日志记录功能

一、什么是 Java 注解?

想象一下,你正在写一本日记,你可以在某些页面上贴上彩色的便签,上面写着一些关键词或者提醒。在 Java 中,注解就像是这些便签,它可以贴在类、方法、变量等程序元素上,为它们添加额外的信息。

注解本身不会改变程序的运行逻辑,但它们可以被其他工具或者框架读取和处理。比如,编译器可以根据注解来检查代码的正确性,或者框架可以根据注解来自动配置对象。

二、Java 内置注解

Java 自带了一些内置的注解,它们非常实用。

1. @Override

当你想要重写一个父类的方法时,可以使用 @Override 注解。这个注解就像是一个标志,告诉编译器你正在重写一个方法。如果你的方法签名不正确,编译器会报错,这样可以避免一些错误。
例如:

package java_core_27;

public class Parent {
	
	 public void sayHello() {
	        System.out.println("Hello from parent!");
	    }
}

class Child extends Parent {
    @Override
    public void sayHello() {
        System.out.println("Hello from child!");
    }
}

很显然,运行结果为:

Hello from child!

2. @Deprecated

如果你有一个方法或者类已经过时了,不建议再使用,可以使用 @Deprecated 注解。
例如:

@Deprecated
public class TestDeprecated {
	
}	

当其他程序员在使用这个注解标记的方法时,会有 删除线 警示。

在这里插入图片描述

3. @SuppressWarnings

有时候,编译器会发出一些警告,但是你可能知道这些警告是不必要的,或者你有特殊的原因不想处理这些警告。例如,对于上述过时的方法就有如下警告:

Multiple markers at this line
	- The constructor TestDeprecated() is deprecated
	- The type TestDeprecated is deprecated
	- The type TestDeprecated is deprecated

这时,你可以使用 @SuppressWarnings 注解来抑制这些警告。

public class Test {
	
	@SuppressWarnings("deprecation")
	public static void main(String[] args) {
		//过时的方法
		TestDeprecated testDeprecated = new TestDeprecated();
		testDeprecated.test();
	}
	
}	

三、什么是元注解?

元注解就是用来注解注解的注解。听起来有点绕,但是其实很简单。元注解可以为我们自定义的注解添加一些属性和行为。
比如,@Retention 元注解可以指定一个注解的生命周期。它有三个取值:

  • RetentionPolicy.SOURCE:注解只在源代码中有效,编译后就会被丢弃。
  • RetentionPolicy.CLASS:注解在编译后的字节码文件中有效,但在运行时不可用。
  • RetentionPolicy.RUNTIME:注解在运行时仍然有效,可以被反射机制读取。
    @Target 元注解可以指定一个注解可以应用的程序元素类型。比如,可以指定一个注解只能应用于方法、类、变量等。

四、Java 自定义注解实现统一日志

接下来,我们使用自定义注解实现一个日志打印的场景:

1. 自定义注解类 LogAnnotation

定义一个自定义注解 LogAnnotation,用于标记需要记录日志的方法。这个注解可以指定一些属性,也可以不指定,仅作为一个标记使用。

package com.jsglxx.demo.utils;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface LogAnnotation {

}

2. 日志记录切面类 LogAspect

  • 创建一个切面类,使用 @Aspect 注解标记该类为一个切面。
  • 在切面类中定义一个环绕通知方法,使用 @Around 注解并指定要拦截的连接点为带有自定义注解的方法 @annotation(com.jsglxx.demo.utils.LogAnnotation)
  • 在环绕通知方法中,通过 ProceedingJoinPoint 对象获取要执行的方法信息,在方法执行前可以记录日志表示进入方法,然后调用 joinPoint.proceed() 执行被拦截的方法,最后在方法执行后再次记录日志表示退出方法,并返回方法的执行结果。
package com.jsglxx.demo.utils;

import ch.qos.logback.classic.Logger;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class LogAspect {

    private final Logger logger = (Logger) LoggerFactory.getLogger(LogAspect.class);

    @Around("@annotation(com.jsglxx.demo.utils.LogAnnotation)")
    public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
        logger.info("进入方法:{}", joinPoint.getSignature().getName());
        Object result = joinPoint.proceed();
        logger.info("退出方法:{}", joinPoint.getSignature().getName());
        return result;
    }
}

3. 在服务类中使用自定义注解

在需要记录日志的服务类方法上添加自定义注解 LogAnnotation

package com.jsglxx.demo.service;

import org.springframework.stereotype.Service;
import com.jsglxx.demo.utils.LogAnnotation;

@Service
public class TestService {

    @LogAnnotation
    public void testMethod() {
        System.out.println("这是一个测试方法。");
    }
}

4. 配置和启动应用-测试

  • 在 Spring Boot 主启动类上添加必要的注解,如 @SpringBootApplication。如果切面类不在主启动类所在的包或子包中,可以通过 @ComponentScan 注解指定切面类所在的包路径,确保切面类被 Spring 容器扫描到。
  • 启动 Spring Boot 应用,当调用被标注了自定义注解的方法时,切面类中的逻辑会自动生效,记录方法的进入和退出日志。
package com.jsglxx.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

import com.jsglxx.demo.service.TestService;

@SpringBootApplication(/* scanBasePackages = {"com.jsglxx.service", "其他需要扫描的包"} */)
@EnableAspectJAutoProxy
public class DemoApplication {
	
	public static void main(String[] args) {
		ConfigurableApplicationContext context = SpringApplication.run(DemoApplication.class, args);
        TestService testService = context.getBean(TestService.class);
        testService.testMethod();
	}

}

结束语

通过以上步骤,就可以在 Spring Boot 应用中利用自定义注解和 AspectJ 实现统一的日志记录功能,方便地对特定方法进行日志跟踪和监控。

遇见即是缘分,关注🌟、点赞👍、收藏📚,让这份美好延续下去!

🌟 对技术管理感兴趣 请关注 ⬇ 【 技术管理修行】

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值