1.说明
本文档根据B站UP主分享内容整理,视频原版连接:【IT老齐140】非常实用!Spring AOP与自定义注解实现共性需求
2.介绍
Spring AOP可以帮助我们Java在不修改源代码的前提下实现功能增强,其底层实现基于Java动态代理 或者CGLIB。
以往我们使⽤execution选定具体利⽤AOP扩展哪些类
@Around(value = "execution(* com.fblinux.aop.controller.HelloController.hello(..));")
3.应用场景
需要灵活使用共性需求的地方都可以使用该方案
- 收集上报指定关键方法的入参,执行时间,返回结果等关键信息,用作后期的调优。
- 关键方法在幂等性的前置校验(基于本地消息表)
- 类似于 Spring-Retry 模块,提供关键方法多次调用重试机制
- 提供关键方法自定义的快速熔断,服务降级等职责
- 关键⽅法的共性⼊参校验
- 关键方法在执行后的扩展行为,利如记录日志,启动其他任务等。
4.开发过程
<!--主要是用于创建AOP切面的使用--> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> </dependency>
(2)新建自定义注解,利用@interface关键字自定义注解
//注解用在方法上 @Target(ElementType.METHOD) //@Retention作用是定义被它所注解的注解保留多久额,RUNTIME运行时,就是这个注解的存活时间 @Retention(RetentionPolicy.RUNTIME) public @interface AnnotationTest { }
(3)开发切面类,模拟了一个数据上报服务器的过程
//关键代码1:说明当前对象是一个切面 @Aspect //关键代码2:@Component允许在Spring IOC对当前对象实例化并管理 @Component public class MethodExporterAspect { //关键代码3:说明切面的作用范围,任何增加@AnnotationTest的目标方法都将在执行该切面方法 //@Around环绕通知,最强大的通知类型,可以控制方法入参,执行,返回结果等各方面细节 @Around("@annotation(com.fblinux.spring5.aopanno.AnnotationTest)") //这表示AnnotationTest注解修饰的方法使用这个自定义切面进行增强 public Object methodExporter(ProceedingJoinPoint joinPoint) throws Throwable{ long st = System.currentTimeMillis(); // 执行目标方法,获取方法返回值 Object proceed = joinPoint.proceed(); long et = System.currentTimeMillis(); ObjectMapper mapper = new ObjectMapper(); // 将入参JSON序列化 String jsonParam = mapper.writeValueAsString(joinPoint.getArgs()); // 将返回结果JSON序列化 String jsonResult = null; if(proceed != null){ jsonResult = mapper.writeValueAsString(proceed); }else{ jsonResult = "null"; } //模拟上报过程 log.info("正在上报服务器调⽤过程:\ntarget:{}.{}()\nexecution:{}ms,\nparameter:{}\nresult:{}" ,joinPoint.getTarget().getClass().getSimpleName() ,joinPoint.getSignature().getName() ,(et-st) ,jsonParam ,jsonResult); return proceed; } }
(4)切面测试代码,只要是需要上报数据的方法只需要添加我们的自定义注解就可以实现,不需要其他任何多余的步骤。
//⽬标⽅法上增加⾃定义注解 @RestController public class SampleController { @AnnotationTest @GetMapping("/list") public Map list(int page , int rows){ Map result = new LinkedHashMap(); result.put("code", "0"); result.put("message", "success"); try { Thread.sleep(new Random().nextInt(1000)); } catch (InterruptedException e) { e.printStackTrace(); } return result; } }
访问接口测试:
http://localhost:8080/list?page=1&rows=100
转载请注明:西门飞冰的博客 » SpringAOP与自定义注解实现共性需求