前言
在SpringBoot开发中,注解(Annotation)是简化配置、提升开发效率的利器。通过自定义注解,我们可以实现业务逻辑与基础功能的解耦,让代码更加优雅。本文将带你从零开始创建自定义注解,并结合AOP实现日志记录功能。
一、注解基础知识回顾
1.1 元注解
Java提供了用于定义注解的元注解:
-
@Target
:指定注解作用范围(类、方法、字段等) -
@Retention
:指定注解生命周期(源码、编译期、运行时) -
@Documented
:包含在Javadoc中 -
@Inherited
:允许子类继承
1.2 注解本质
注解本质是接口,通过反射机制在运行时获取并处理。
二、创建自定义注解
2.1 定义日志注解
@Target(ElementType.METHOD) // 作用于方法
@Retention(RetentionPolicy.RUNTIME) // 运行时生效
public @interface OperationLog {
String module() default ""; // 模块名称
String type() default ""; // 操作类型
String description() default ""; // 操作描述
}
2.2 注解参数说明
-
成员变量通过
类型 名称()
格式声明 -
default
可设置默认值 -
参数类型支持基本类型、String、Class、枚举等
三、结合AOP实现功能
3.1 添加AOP依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
3.2 实现切面逻辑
@Aspect
@Component
public class LogAspect {
// 定义切点:拦截带有@OperationLog注解的方法
@Pointcut("@annotation(com.example.demo.annotation.OperationLog)")
public void logPointCut() {}
@Around("logPointCut()")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
// 获取注解信息
OperationLog logAnnotation = method.getAnnotation(OperationLog.class);
String module = logAnnotation.module();
String type = logAnnotation.type();
String desc = logAnnotation.description();
// 记录方法执行前日志
System.out.println("【操作日志】模块:" + module
+ " | 类型:" + type
+ " | 描述:" + desc);
long startTime = System.currentTimeMillis();
Object result = joinPoint.proceed();
long endTime = System.currentTimeMillis();
// 记录方法执行耗时
System.out.println("方法执行耗时:" + (endTime - startTime) + "ms");
return result;
}
}
四、实际应用示例
4.1 在Controller中使用
@RestController
@RequestMapping("/user")
public class UserController {
@OperationLog(module = "用户管理", type = "查询", description = "获取用户详情")
@GetMapping("/detail/{id}")
public User getUserDetail(@PathVariable Long id) {
// 业务逻辑...
return userService.getUserById(id);
}
}
4.2 执行结果
【操作日志】模块:用户管理 | 类型:查询 | 描述:获取用户详情
方法执行耗时:58ms
五、扩展应用场景
-
权限校验:
@RequirePermission("user:delete")
-
接口限流:
@RateLimit(limit=100, period=60)
-
事务管理:
@DistributedTransaction
-
数据脱敏:
@SensitiveData
-
性能监控:统计方法执行时间
六、注意事项
-
确保切面类被Spring管理(使用@Component)
-
注意切入点表达式的正确性
-
优先使用环绕通知(@Around)获取完整控制权
-
合理处理异常避免影响业务逻辑
总结
通过自定义注解+AOP的组合,我们可以实现声明式的功能扩展。这种设计模式不仅提高了代码的可读性和可维护性,还能有效减少重复代码。建议大家在实际开发中根据业务需求灵活运用这种方案。
欢迎在评论区交流你的注解使用心得!
如果觉得有帮助,请点赞⭐收藏支持~