一、什么是 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 实现统一的日志记录功能,方便地对特定方法进行日志跟踪和监控。
遇见即是缘分,关注🌟、点赞👍、收藏📚,让这份美好延续下去!
🌟 对技术管理感兴趣 请关注 ⬇ 【 技术管理修行】