Spring 源码之AOP

前言

整理前面spring源码中aop的部分,主要梳理主要的调用关系,期望能看出来目标对象的代理是实现的,定义的增强操作怎样被插入到目标方法的执行中去的。根据proxy的创建,和调用为主要线索。为了使得线索上简单,做了如下简化:

  • 作为两种代理方式只是介绍了JdkDynamicAopProxy ,省略了ObjenesisCglibAopProxy,关于CGLIB的可以参照?AOP 的利器:ASM 3.0 介绍
  • ?省略了Advisor,Advice,Point这些角色的解释及其使用详细,这三个重要接口在使用中的实现还是有挺多细节的。
  • ?顺序的调用关系的代码都贴出来,但是了解主要逻辑,只要关注高亮部分即可。
  • 关于FactoryBean的使用时spring IOC的内容,没有展开
  • 另外一种Proxy创建的工厂ProxyFactory未介绍
  • JdkDynamicAopProxy中关于java 动态代理原理未展开

一、主要代码流程:

ProxyFactoryBean利用IOC的方式根据配置构造AOP代理。根据配置构造String[] interceptorNames属性来配置已经定义好的通知器Advisor,String targetName来定义目标对象等重要属性。然后在入口getObject方法中构造和返回代理对象,代理对象的构造由DefaultAopProxyFactory类完成。根据是否定义了接口来选择使用JdkDynamicAopProxy,还是ObjenesisCglibAopProxy。

在目标方法被调用时,jdk动态代理的invocationhandler接口对象的invoke方法会被调用。根据拦截器串,代理对象,代理方法构造ReflectiveMethodInvocation对象,并调用其proceed方法。在proceed方法中根据配置的advice在代理方法的执行的合适位置(如执行前、执行后、异常时)执行拦截器中定义的方法,从而达到切面的效果。

二、主要代码调用

1.?ProxyFactoryBean继承自FactoryBean,因此也是一种FactoryBean,是通过IOC的Bean配置来生成,对应的有另外一个类?ProxyFactory是通过编码的方式来配置。这里只看一般使用的ProxyFactoryBean。

AdvisedSupport-hierarchy

 

 

2. 根据配置 初始化Advisor。

advisor在源码中的定义是:Base interface holding AOP advice (action to take at a joinpoint) and a filter determining the applicability of the advice (such as a pointcut). 最主要的方法就是Advice getAdvice();方法。作为通知器,其主要作用就是要通知的内容,封装在Advice对象中。尤其应用的是其下的的PointcutAdvisor,通知在什么情况下做什么事情,在代码上就是把Pointcut接口和Advice接口联系在一起。?Spring采用AOP联盟的Advice作为超级接口,扩展了很多子接口,比如BeforeAdvice,AfterAdvice等。Pointcut作为切点的抽象,其中有一个方法返回一个MethodMatcher,作用很明显,就是说切点决定了要切入哪些方法。这里其实是定义了一个匹配规则。比如正则匹配等等。

advisor

? ? ? ? ? ? ??

3. ?在newPrototypeInstance方法中构建代理,getSingletonInstance()方法中构建代理的方式类似。对通知器进行初始花,通知器链封装了一系列拦截器,并构造代理类。

4. ?DefaultAopProxyFactory创建代理,当接口则用JdkDynamicAopProxy,不是接口就用ObjenesisCglibAopProxy。

5. JdkDynamicAopProxy?从advised对象中取得代理对象的代理接口配置,然后调用Proxy的newProxyInstance方法,得到Proxy代理对象。指定三个参数:类加载器、代理接口、Proxy回调方法所在对象该对象其实就是JdkDynamicAopProxy。

?至此代理构造完成。

以下是通过JdkDynamicAopProxy 来实现AOP拦截。

6.?JdkDynamicAopProxy实现了InvocationHandler接口,根据代理原理,定义了代理的每个类的方法在被执行时都会被执行代理类中定义的InvocationHandler类型对象的invoke方法。即每个方法执行都会被检查。在该接口的invoke方法中获得拦截器chain,并且执行拦截器方法。在invoke方法中构造了一个ReflectiveMethodInvocation对象,并调用其proceed方法。

7. ?其proceed方法中递归的考察拦截器串interceptorsAndDynamicMethodMatchers中触发满足条件的拦截器的执行,并执行目标对象target的对应方法。

7. ?MethodInterceptor 的invoke方法,其实就是拦截器的对应方法,根据不同的拦截器类型有不同的方法。

inteceptor

 

AfterReturningAdviceInterceptor 的invoke方法,即先执行对应的MethodInvocation的proceed方法,执行完后执行advice的对应方法。

而对应的MethodBeforeAdviceInterceptor方法中,先执行advice中定义的方法,然后才执行MethodInvocation的proceed方法。

MethodInterceptor的?Object invoke(MethodInvocation invocation)方法中执行完插入的方法(before,after这样的方法)以外,还会在和适当的地方调用执行MethodInvocation 的proceed方法,即把执行任务往下传递,体现了典型的责任链设计模式(Chain of Responsibility)。

invoke-proceed

 

如假设定义了两个interceptor,执行的顺序是:

  1. 1.在ReflectiveMethodInvocation的proceed方法中获得第一个?interceptor1执行其invoke方法
  2. ?执行第一个拦截器interceptor1的前置方法
  3. 获取下一个拦截器inteceptor2,执行下个拦截器的前置方法
  4. 执行inteceptor2的前置方法
  5. 执行目标方法
  6. 执行inteceptor2的后置方法
  7. 执行inteceptor1的后置方法

?完。

原创文章。为了维护文章的版本一致、最新、可追溯,转载请注明: 转载自idouba

本文链接地址: Spring 源码之AOP


, , ,

No comments yet.

发表评论