简介
咱们在文章《Spring AOP 与 AspectJ 的比照及利用》介绍了 AOP 的应用,这篇文章解说一下 AOP 与注解的整合,通过注解来应用 AOP,会十分不便。为了简便,咱们还是来实现一个计时的性能。
整合过程
首先创立一个注解:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface PkslowLogTime {}
而后在一个 Service 中应用注解:
@Service
@Slf4j
public class TestService {
@PkslowLogTime
public void fetchData() {log.info("fetchData");
try {Thread.sleep(500);
} catch (InterruptedException e) {throw new RuntimeException(e);
}
}
}
这个 Service 的办法会在 Controller 中调用:
@GetMapping("/hello")
public String hello() {log.info("------hello() start---");
test();
staticTest();
testService.fetchData();
log.info("------hello() end---");
return "Hello, pkslow.";
}
接着是要害一步,咱们要实现切面,来找到注解并实现对应性能:
@Aspect
@Component
@Slf4j
public class PkslowLogTimeAspect {@Around("@annotation(com.pkslow.springboot.aop.PkslowLogTime) && execution(* *(..))")
public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {log.info("------PkslowLogTime doAround start------");
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
// Get intercepted method details
String className = methodSignature.getDeclaringType().getSimpleName();
String methodName = methodSignature.getName();
// Measure method execution time
StopWatch stopWatch = new StopWatch(className + "->" + methodName);
stopWatch.start(methodName);
Object result = joinPoint.proceed();
stopWatch.stop();
// Log method execution time
log.info(stopWatch.prettyPrint());
log.info("------PkslowLogTime doAround end------");
return result;
}
}
@Around("@annotation(com.pkslow.springboot.aop.PkslowLogTime) && execution(* *(..))")
这个表达式很要害,如果不对,将无奈正确辨认;还有可能呈现屡次调用的状况。屡次调用的状况能够参考:Stackoverflow
这里应用了 Spring 的 StopWatch 来计时。
测试
通过 maven build 包:
$ mvn clean package
日志能够看到有对应的织入信息:
[INFO] Join point 'method-execution(java.lang.String com.pkslow.springboot.controller.TestController.hello())' in Type 'com.pkslow.springboot.controller.TestController' (TestController.java:22) advised by around advice from 'com.pkslow.springboot.aop.ControllerAspect' (ControllerAspect.class(from ControllerAspect.java))
[INFO] Join point 'method-execution(java.lang.String com.pkslow.springboot.controller.TestController.hello())' in Type 'com.pkslow.springboot.controller.TestController' (TestController.java:22) advised by before advice from 'com.pkslow.springboot.aop.ControllerAspect' (ControllerAspect.class(from ControllerAspect.java))
[INFO] Join point 'method-execution(void com.pkslow.springboot.controller.TestController.test())' in Type 'com.pkslow.springboot.controller.TestController' (TestController.java:31) advised by around advice from 'com.pkslow.springboot.aop.ControllerAspect' (ControllerAspect.class(from ControllerAspect.java))
[INFO] Join point 'method-execution(void com.pkslow.springboot.controller.TestController.test())' in Type 'com.pkslow.springboot.controller.TestController' (TestController.java:31) advised by before advice from 'com.pkslow.springboot.aop.ControllerAspect' (ControllerAspect.class(from ControllerAspect.java))
[INFO] Join point 'method-execution(void com.pkslow.springboot.controller.TestController.staticTest())' in Type 'com.pkslow.springboot.controller.TestController' (TestController.java:37) advised by around advice from 'com.pkslow.springboot.aop.ControllerAspect' (ControllerAspect.class(from ControllerAspect.java))
[INFO] Join point 'method-execution(void com.pkslow.springboot.controller.TestController.staticTest())' in Type 'com.pkslow.springboot.controller.TestController' (TestController.java:37) advised by before advice from 'com.pkslow.springboot.aop.ControllerAspect' (ControllerAspect.class(from ControllerAspect.java))
[INFO] Join point 'method-execution(void com.pkslow.springboot.service.TestService.fetchData())' in Type 'com.pkslow.springboot.service.TestService' (TestService.java:12) advised by around advice from 'com.pkslow.springboot.aop.PkslowLogTimeAspect' (PkslowLogTimeAspect.class(from PkslowLogTimeAspect.java))
启动利用后拜访接口,日志如下:
总结
通过注解能够实现很多性能,也十分不便。而且注解还能够增加参数,组合应用更完满了。
代码请看 GitHub: https://github.com/LarryDpk/p…