当前位置: 首页 > 后端技术 > Java

Springboot整合AOP和注解,实现丰富的切面功能

时间:2023-04-01 21:16:29 Java

Springboot集成AOP和注解实现丰富的切面功能为了简单起见,我们来实现一个定时功能。集成过程首先创建一个注解:@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.METHOD)public@interfacePkslowLogTime{}然后在服务中使用注解:@Service@Slf4jpublicclassTestService{@PkslowLogTimepublicvoidfetchData(){log.info("fetchData");尝试{Thread.sleep(500);}catch(InterruptedExceptione){thrownewRuntimeException(e);}}}这个Service的方法会在Controller中调用:@GetMapping("/hello")publicStringhello(){log.info("------hello()start---");测试();静态测试();testService.fetchData();log.info("------你好()结束---");return"Hello,pkslow.";}接下来是关键的一步,我们需要实现切面,找到注解并实现相应的功能:@Aspect@Component@Slf4jpublicclassPkslowLogTimeAspect{@Around("@annotation(com.pkslow.springboot.aop.PkslowLogTime)&&execution(**(..))")publicObjectdoAround(ProceedingJoinPointjoinPoint)throwsThrowable{log.info("------PkslowLogTimedoAroundstart------");MethodSignaturemethodSignature=(MethodSignature)joinPoint.getSignature();//获取拦截的方法详情StringclassName=methodSignature.getDeclaringType().getSimpleName();StringmethodName=methodSignature.getName();//测量方法执行时间StopWatchstopWatch=newStopWatch(className+"->"+methodName);stopWatch.start(methodName);Objectresult=joinPoint.proceed();stopWatch.stop();//记录方法执行时间log??.info(stopWatch.prettyPrint());log.info("------PkslowLogTimedoAroundend------");返回结果;}}@Around("@annotation(com.pkslow.springboot.aop.PkslowLogTime)&&execution(**(..))")这个表达式很关键,如果错误,将无法正确识别;可能有多次调用。多次调用请参考to:Stackoverflow在这里使用Spring的StopWatch来计时。测试通过maven构建包:$mvncleanpackage日志可以看到有对应的编制信息:[INFO]Joinpoint'method-execution(java.lang.Stringcom.pkslow.springboot.controller.TestController.hello())'在类型'com.pkslow.springboot.controller.TestController'(TestController.java:22)中根据来自'com.pkslow.springboot.aop.ControllerAspect'(ControllerAspect.class(fromControllerAspect.java))的周围建议建议[INFO]在类型'com.pkslow.springboot.controller.TestController'(TestController.java:22)中加入点'method-execution(java.lang.Stringcom.pkslow.springboot.controller.TestController.hello())'(TestController.java:22)在来自'com.pkslow.springboot.aop.ControllerAspect'的建议之前(ControllerAspect.class(来自ControllerAspect.java))[INFO]加入点'method-execution(voidcom.pkslow.springboot.controller.TestController.test())'在类型'com.pkslow.springboot.controller.TestController'(TestController.java:31)中由来自'com.pkslow.springboot.aop.ControllerAspect'(ControllerAspect.class(fromControllerAspect.java))[INFO]Joinpoint'method-execution(voidcom.pkslow.springboot.controller.TestController.test())'inType'com.pkslow.springboot.controller.TestController'(TestController.java:31)由'com.pkslow.springboot.aop.ControllerAspect'(ControllerAspect.class(fromControllerAspect.java))[INFO]Joinpoint'method-execution(voidcom.pkslow.springboot.controller.TestController.staticTest())'inType'com.pkslow.springboot.controller.TestController'(TestController.java:37)由'com.pkslow.springboot.aop.ControllerAspect'(ControllerAspect.class(ControllerAspect.class(来自ControllerAspect.java))[INFO]在类型'com.pkslow.springboot.controller.TestController'(TestController.java:37)由'com.pkslow.springboot.aop.ControllerAspect'(ControllerAspect.class(来自ControllerAspect.java))[INFO]在类型'com.pkslow.springboot.service.TestService'中加入点'method-execution(voidcom.pkslow.springboot.service.TestService.fetchData())'(TestService.java:12)advisedbyaroundadvicefrom'com.pkslow.springboot.aop.PkslowLogTimeAspect'(PkslowLogTimeAspect.class(fromPkslowLogTimeAspect.java))启动应用程序访问接口后,日志如下:总结很多功能可以通过annotations,也很方便,在annotations的时候还可以添加参数,让组合更加完美。代码请查看GitHub:https://github.com/LarryDpk/p...