Springboot中的面向切面编程以及查询系统中所有方法执行时间的案例

面向切面编程:

 是通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术,可以对业务逻辑的各个部分进行隔离,针对业务处理过程中的切面进行提取.面对的是处理过程中的某个步骤,以切面作为基本的逻辑处理单元。注意AOP不会代替OOP,AOP实际上是java语言的拓展。

  简单来说就是,一个方法执行前或执行后,或执行前后,或抛出异常时,执行一些固定的逻辑,这些逻辑不必在每个方法执行前后都写一次,而是把它们找出来作为切面,写一次就行了。

 

面向切面编程的核心概念:

  连接点:就是程序执行的某个特定位置(比如类初始化前、初始化后、某个方法调用前、调用后、报出异常后5种),但是注意Aop只认方法的连接点,所以一般一个方法就是一个连接点。

  切点:Aop定位到特定的连接点的方式就叫切点。

  增强(也可以叫通知,是对Advice的翻译):织入到目标类的连接点上的代码。

  织入(Weaving):是将增强添加到目标类中具体连接点上的过程。Aop有编译器、类装载、动态代理三种织入方式,但是springAop使用动态代理。

  引介(Introduction):是一种特殊的增强,因为它是对类添加一些属性和方法。

  代理(Proxy):一个类被aop织入增强后,就产出了一个代理类。

  切面(Aspect):切面由切点和增强或引介组成。

 

案例需求:

  假如你的系统(基于springboot)现在响应时间非常长,你需要知道是具体的哪些方法用时长,好方便你优化它们,一般来说需要在每个方法里面的第一行获取当前时间,再在return前的第一行获取当前时间,两个时间相减就是此方法的耗时,但是这样做实在是太麻烦了,并且如果你的系统里面有大量的方法,将会造成巨大的工作量。

 

解决思路:

  每个方法执行前后,其实可以看做两个连接点,而这些连接点所需要执行的业务逻辑都是一样的,即获取当前时间,那么就可以用到aop,将这些相同的业务行为取出并封装起来,这样只需要指定切点即可对所有方法完成操作。

 

核心代码:

  切面类:

  

@Component
@Aspect
public class LogAspect {

    @Pointcut("execution( 你自己的切点路径 )")//指定切点路径
public void pointcut() { } @Around("pointcut()") public Object log(ProceedingJoinPoint joinPoint) throws Throwable { //获取目标对象 Object target = joinPoint.getTarget(); //获取目标对象方法 MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature(); Method method = target.getClass().getMethod( methodSignature.getName(), methodSignature.getParameterTypes()); //获取注解对象实例,并通过stopWatch工具类来进行方法调用计时 //MyLog log = method.getAnnotation(MyLog.class); StopWatch stopWatch = new StopWatch(); stopWatch.start(); Object result = joinPoint.proceed(); stopWatch.stop(); System.out.println("【Normal】"); System.out.println("Log =>\t调用方法:" + method.getName()); System.out.println("Log =>\t消耗时间:" + stopWatch.getTotalTimeMillis() + "ms\n"); return result; } }

 

posted @ 2023-10-03 15:45  斌哥的小弟  阅读(193)  评论(0)    收藏  举报