从底层分析并详解SpringAOP底层实现

首先分析AOP的实现

  首先切面(Advisor)由通知(Advice)和切点(Pointcut)组成

  包括前置通知后置通知等等最终都会被转化为实现 MethodInterceptor 接口的环绕通知

  先看一段代码了解一下是aop是怎么运作的

  

首先定义了两个类实现了MethodInterceptor接口,这里的 MethodInvocation 是对原始方法的包装同时也是AOP通知功能的实现方式。

首先这里method,target,args都是原始对象的方法参数用于反射调用。构造参数中传入集合的是刚刚来两个实现MethodInterceptor的类。

当这里的proceed方法被调用时,会有一个初始化为0的参数,作用是记录这里第几个调用的Advisor,当所有的Advisor调完后就会执行真正的原始方法。从而形成了递归调用,效果就是我们看到的环绕通知

这是主程序加效果

接下来我们看一下Spring如何实现的

实现时要使用@EnableAspectJAutoProxy注解,它的作用是通过封装Import注解导入一些其他类,它导入了 AnnotationAwareAspectJAutoProxyCreator 类

由于此类是被保护的所以我采用继承的方法去调用相关方法,并自定义了一个Advisor,同时还通过注解去引入

 

这是主程序

@Aspect注解的解析

首先这是一个Bean后处理器方法

首先把原始工厂和beanName封装在 MetadataAwareAspectInstanceFactory 类中,此类用于保存@Aspect注解标注的类信息,紧接着调用 this.advisorFactory.getAdvisors 方法

此方法根据类获得方法信息以及注解信息封装为 InstantiationModelAwarePointcutAdvisorImpl 这种类型的Advisor。

Advisor由Advice和切点表达式组成

通过 findEligibleAdvisors 方法获取工厂中所有的Advisor,然后根据bean的类型进行匹配做代理

不过这里值得注意的是导入了一个org.springframework.aop.interceptor.ExposeInvocationInterceptor 这个类,这个类是为了把信息存放在ThreadLocal中暴露给整个线程

顺带说一下这里的wrapIfNecessary就是存放在三级缓存的那个bean代理的创建方法

重点在 wrapIfNecessary 方法,这个方法内部会在 getAdvicesAndAdvisorsForBean 方法中

调用 findEligibleAdvisors 方法

然后调用createProxy方法

重点来了

此方法内部创建一个ProxyFactory对象,他会把传入的Advisor通过装饰器模式把他们转化为实现了MethodInterceptor接口的环绕通知

proxyTargetClass 和  exposeProxy 

是@EnableAspectJAutoProxy两个可选项,第一个为false代表默认使用jdk生成动态代理,true的话用Cglib。而exposeProxy为true则代表把生成的代理对象存放在ThreadlocalMap中,这样就可以解决嵌套调用时事务失效的功能。

然后调用getProxy方法生成代理对象

然后我们观察代理对象的代理方法

这里的advised就是ProxyFactory 紧接着调用 getInterceptorsAndDynamicInterceptionAdvice 方法

此方法内部获取所有的Advisor然后进行方法匹配,如果匹配就会把Advice包装为环绕通知

首先获得advice,然后包装

就是这样进行包装,然后通过MethodInvocation获取这些环绕通知,调用invoke这样就可以实现递归嵌套调用,比如前置通知转化为环绕通知后只需要在proceed之前调用就行,就完成了转化

最终调用

就是通过创建 Invocation 然后递归调用

这是官方的proceed实现和我们最开始写的类似

由于上面说了会默认加入一个 ExposeInvocationInterceptor 类用于暴露代理接下来就是证明

这里的invocation就是一个ThreadLocal对象它的作用就是让别的MethodInteceptor也可以使用

就好比通过转化后的 MethodBeforeAdviceInterceptor 就需要用

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring AOP底层实现原理主要是基于动态代理。Spring AOP通过使用代理模式,在运行时动态地为目标对象生成一个代理对象,然后通过代理对象来完成对目标对象的方法增强。 具体实现步骤如下: 1. 定义切面类:切面类是一个普通的Java类,用于定义切点和增强逻辑。切点是指确定在何处应用增强逻辑的表达式。增强逻辑是指在切点处插入的具体行为,如日志记录、事务管理等。 2. 配置切面:在Spring配置文件中,通过<aop:aspect>标签配置切面类,并使用<aop:pointcut>标签定义切点表达式。 3. 创建代理对象:在Spring容器启动时,会解析配置文件并扫描所有的Bean对象。当Spring发现某个Bean对象需要进行AOP增强时,会为该对象动态地创建一个代理对象。代理对象可以通过JDK动态代理或者CGLIB动态代理来创建。 4. 方法调用时的增强逻辑:当通过代理对象调用方法时,实际上是调用了代理对象中的方法。在代理对象的方法中,会根据切点表达式判断是否需要插入增强逻辑。如果需要插入增强逻辑,则会在方法的前后或者异常抛出时执行相应的增强操作。 总结起来,Spring AOP底层实现原理是通过动态代理,在运行时为目标对象生成代理对象,并在代理对象中实现对目标对象方法的增强。这个过程是在Spring容器启动时进行的,通过配置文件中的切面定义和切点表达式,确定增强逻辑的插入位置。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值