Spring AOP整合自定义注解
一、前言
- 自定义注解与Spring AOP结合可以应用于各种横切关注点的处理场景,包括日志记录、安全验证、缓存管理、事务管理、性能监控和异常处理等。通过使用AOP切面,可以将这些横切关注点的逻辑与业务逻辑解耦,并实现集中管理和复用,提高代码的可读性、可维护性和可扩展性。
- 日志记录:通过自定义注解,可以标记需要进行日志记录的方法或类。使用AOP切面,可以在方法执行前、执行后或异常发生时记录日志信息,而无需在每个方法中编写重复的日志记录代码。
- 安全验证:通过自定义注解,可以标记需要进行安全验证的方法或类。使用AOP切面,可以在方法执行前进行权限验证、身份验证等安全控制操作,以保证系统的安全性。
- 缓存管理:通过自定义注解,可以标记需要进行缓存管理的方法或类。使用AOP切面,可以在方法执行前检查缓存中是否存在相应的结果,如果存在,则直接返回缓存结果,避免重复执行耗时的操作。
- 事务管理:通过自定义注解,可以标记需要进行事务管理的方法或类。使用AOP切面,可以在方法执行前开启事务,在方法执行后提交或回滚事务,确保数据的一致性和完整性。
- 事务管理:通过自定义注解,可以标记需要进行事务管理的方法或类。使用AOP切面,可以在方法执行前开启事务,在方法执行后提交或回滚事务,确保数据的一致性和完整性。
- 异常处理:通过自定义注解,可以标记需要进行异常处理的方法或类。使用AOP切面,可以在方法执行过程中捕获异常,并进行统一的异常处理操作,例如记录异常日志、返回统一的错误码等。
- 整合自定义注解与Spring AOP结合使用有以下几点好处:
- 代码解耦:通过使用自定义注解,可以将横切关注点(cross-cutting concerns)与业务逻辑进行解耦。将横切关注点的逻辑从业务代码中抽离出来,以注解的形式标记需要被切面处理的方法或类,提高了代码的可读性和可维护性。
- 重用性和灵活性:通过自定义注解,可以在不同的方法或类上进行标记,使得切面逻辑可以在多个地方进行重用。同时,通过AOP的机制,可以动态地在运行时将切面逻辑织入到被标记的方法或类中,提供了更大的灵活性。
- 横切关注点的集中管理:通过使用自定义注解,可以将不同的横切关注点集中管理。在切面类中,可以定义多个切面逻辑,并使用不同的注解来匹配不同的方法或类。这样,可以将相同的横切关注点逻辑应用于多个地方,实现了逻辑的复用和集中管理。
- 提高开发效率:通过使用自定义注解和Spring AOP,可以减少重复的代码和冗余的逻辑。横切关注点的逻辑只需要在切面中定义一次,然后通过注解的方式应用于多个方法或类中。这样可以提高开发效率,并减少代码的维护成本。
二、实现
-
创建自定义注解
/** * 监控方法执行情况 */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface Monitoring { }
-
创建切面类
@Aspect @Component @Slf4j public class MonitoringAspect { @Around("@annotation(com.aben.annotation.annotation.Monitoring)") public Object Monitoring(ProceedingJoinPoint joinPoint) throws Throwable { // 入参 Object[] args = joinPoint.getArgs(); // 耗时检测 long startTime = new Date().getTime(); // 出参 Object proceed = joinPoint.proceed(); long endTime = new Date().getTime(); // 记录日志 log.info("\n正在收集方法执行情况:{\n目标:{}.{};\n耗时:{}ms;\n入参:{};\n出参:{};}" , joinPoint.getTarget().getClass().getName() , joinPoint.getSignature().getName() , (endTime - startTime) , args , proceed); return proceed; } }
-
使用注解
@RestController @RequestMapping("/monitoring") @Slf4j public class MonitoringController { @GetMapping("/test") @Monitoring public String test(String str) { // 执行业务 str = str.replace("hello", "isabener"); return str; } }