详细介绍一下springboot自定义注解的使用方法
在Spring Boot中,自定义注解通常结合AOP(面向切面编程)实现特定功能,如日志记录、权限校验等。以下是详细的使用步骤和示例:
1. 添加依赖
确保项目中包含Spring AOP依赖(Spring Boot Starter AOP):
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
2. 定义自定义注解
使用Java元注解(如@Target
, @Retention
)创建自定义注解。
示例:记录方法执行时间的注解
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.METHOD) // 注解作用在方法上
@Retention(RetentionPolicy.RUNTIME) // 运行时保留
public @interface LogExecutionTime {
String value() default ""; // 可选参数
}
3. 创建切面类处理注解
通过AOP切面拦截带有自定义注解的方法,实现具体逻辑。
示例:记录方法执行时间的切面
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
@Aspect // 声明为切面类
@Component // 注册为Spring Bean
public class LogExecutionTimeAspect {
// 定义切入点:所有被@LogExecutionTime注解的方法
@Around("@annotation(LogExecutionTime)")
public Object logExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {
long startTime = System.currentTimeMillis();
// 执行目标方法
Object result = joinPoint.proceed();
long endTime = System.currentTimeMillis();
long duration = endTime - startTime;
// 获取方法名和注解参数
String methodName = joinPoint.getSignature().getName();
LogExecutionTime annotation = joinPoint.getTarget().getClass()
.getMethod(methodName, joinPoint.getMethod().getParameterTypes())
.getAnnotation(LogExecutionTime.class);
String tag = annotation.value();
System.out.println("方法 " + methodName + " 执行耗时: " + duration + "ms" +
(!tag.isEmpty() ? " [标签: " + tag + "]" : ""));
return result;
}
}
4. 在业务代码中使用注解
在需要增强的方法上添加自定义注解。
示例:在Service中使用
@Service
public class SampleService {
@LogExecutionTime("示例服务") // 使用自定义注解
public void performTask() {
// 模拟耗时操作
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
5. 测试注解效果
调用带有注解的方法,查看控制台输出。
示例:测试类
@SpringBootTest
public class SampleServiceTest {
@Autowired
private SampleService sampleService;
@Test
public void testLogExecutionTime() {
sampleService.performTask();
// 控制台输出:方法 performTask 执行耗时: 1000ms [标签: 示例服务]
}
}
常见应用场景
- 日志记录:自动记录方法入参、返回值、异常信息。
- 权限校验:通过注解拦截请求,检查用户权限。
- 缓存控制:根据注解配置自动缓存方法结果。
- 事务管理:自定义事务控制策略。
- 限流/熔断:实现接口访问频率限制。
注意事项
- 确保切面生效:切面类需被Spring管理(使用
@Component
)。 - 正确设置注解生命周期:
@Retention(RetentionPolicy.RUNTIME)
。 - 切入点表达式:检查
@Around
中的表达式是否正确匹配注解。 - 代理模式:Spring AOP默认使用JDK动态代理,对接口有效;若需代理类,可切换为CGLIB(在Spring Boot中通过
spring.aop.proxy-target-class=true
配置)。
高级用法
- 组合注解:将自定义注解与Spring注解结合,简化配置。
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @RequestMapping(method = RequestMethod.GET, path = "/info") public @interface GetInfo {}
- 注解继承:通过
@Inherited
让子类继承父类的注解。
通过以上步骤,你可以灵活创建并应用自定义注解,增强代码的可读性和复用性。