AOP的实现
体系结构图(备注1)
1.概念
1.1 Advice(通知)
作用:定义在连接点做什么,为切面增强提供织入接口(Spring AOP中主要描述围绕方法调用而注入的切面行为).
如统计方法调用的次数count(CountingBeforeAdvice等)
1.2 PointCut(切点)
作用:决定通知作用于哪个连接点.
1.2.1 MethodMatcher
作用:判断是否需要对当前方法调用进行增强.
如:JdkRegexpMethodPointcut是由基类StaticMethodMatcherPointcut中设置StaticMethodMatcher为MethodMatcher,同时JdkRegexpMethodPointcut也是StaticMethodMatcher的子类.
1.3 Advisor(通知器)
作用:将通知和切点结合.
如:DefaultPointcutAdvisor
其中有2个属性Advice和Pointcut
Pointcut被默认设置为单例的TruePointcut(用TrueMethodMatcher[单例]作为方法匹配要求:永远返回true)
2.建立AopProxy代理对象
2.1 配置ProxyFactoryBean(其中实现AOP的最底层方法)
package org.springframework.aop.framework
2.1.1 配置步骤:
- 定义使用的通知器Advisor(以bean来定义),该通知器定义了通知(Advice).
- 定义proxyFactoryBean(封装AOP的主要类),配置时需要设置AOP实现相关的重要属性(如target,proxyInterface,interceptorNames).
- 定义target属性:需要AOP通知器中的切面应用来增强的对象.
2.1.2 实现:
- 配置ProxyFactoryBean的基类分别实现不同功能:
a.ProxyConfig(数据类):提供配置属性.
b.AdvisedSupport:封装aop对通知和通知器的相关操作(具体对象的创建由该对象的子类完成).
c.ProxyCreatorSupport(辅助类):
注意:具体的AOP代理对象根据不同的需要分别由:ProxyFactoryBean(声明式),AspectJProxyFactory(集成Spring和AspectJ)和ProxyFactory(编程式)完成.
2.2 ProxyFactoryBean生成AopProxy(通过jdk或者CGLIB提供的Proxy特性)
2.2.1 ProxyFactoryBean的getObject()
作用:把需要对target目标对象增加的增强处理(为AOP功能的实现提供服务),都通过该方法进行封装.
流程:
initializeAdvisorChain()
:初始化通知器链( 封装一系列的拦截器,这些拦截器从配置中读取)为代理对象的生成做好准备.a.通知链是否已经初始化(advisorChainInitialized标志位)
b.读取配置中所有的通知器(把通知器的名字给容器的getBean[利用回调实现])
c.addAdvisorOnChainCreation()
(把ioc容器中取得的通知器加入到拦截器链中)
- 生成代理对象(区分单例和多例)
a.getSingletonInstance()
:通过AopProxyFactory(DefaultAopProxyFactory[用ProxyFactoryBean的基类ProxyCreatorSupport(创建ProxyFactoryBean时会初始化它)])取得AopProxy
b.newPrototypeInstance()
注: AopProxy代理对象的生成:
1.需要生成什么样的代理对象,信息都封装在AdvisedSupport(上面的ProxyCreatorSupport也是继承于它)
2.目标对象是接口类:jdk生成(JdkDynamicAopProxy),否则用cglib(CglibProxyFactory)生成.
具体生成(jdk和cglib):
1.JdkDynamicAopProxy.
a—从advised 中取得代理对象的代理接口的配置
b—newProxyInstance()
(需要三个参数:类装载器,代理接口,proxy回调方法所在的对象[该对象(JdkDynamicAopProxy)需要实现InvocationHandler接口定义的Invoke()
方法{提供代理对象的回调入口}]) 得到代理对象.2.Cglib2AopProxy.
a—从advised中取得在IOC中配置的target对象
b—配置Enchancer(如:代理接口,回调方法,)
c—callback()
回调(封装SpringAOP的实现[类似前面的Invoke])
3.Spring AOP拦截器调用的实现
3.1 JdkDynaMicAopProxy的invoke()
拦截(回调实现InvocationHandler接口的invoke()
)
把目标对象,拦截器链等对象作为输入,创建ReflectiveMethodInvocation对象
invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain)
来完成AOP功能实现的封装.
JdkDynaMicAopProxy的invoke()
–>创建ReflectiveMethodInvocation
–>process()
3.2 Cglib2AopProxy的intercept()
拦截
回调具体在DynamicAdvisedInterceptor对象中实现。
getProxy()
–getCallbacks()
–>DynamicAdvisedInterceptor(回调intercept()在该类中实现)
->intercept()
–>CglibMethodInvocation(和上面的ReflectiveMethodInvocation类似[父子关系])
–>process()
3.3 目标对象方法的调用
-
JdkDynaMicAopProxy中
-
AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse)
中具体invoke()
(反射)方法.
Cglib2AopProxy中
-
methodProxy.invoke(target, args)
3.4 AOP拦截器链的调用
jdk和cglib都是通过ReflectiveMethodInvocation中的proceed实现.
迭代调用proceed,逐个进行拦截器的拦截方法,在运行拦截器前,需要对代理方法进行匹配(
matches()
)判断(是否满足切面增强的要求),如果是,则从拦截器中得到通知器,启动通知器的invoke方法进行增强否则proceed()
;
如果已经运行到拦截器链的末尾,就会直接调用目标的实现方法,否则取下一个拦截器继续上卖弄的步骤.
3.5 配置通知器
JdkDynaMicAopProxy中
在ReflectiveMethodInvocation的proceed里 如下:
interceptorOrInterceptionAdice = this.inerceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
Cglib2AopProxy中
在DynamicAdvisedInterceptor的intercept会调用
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method,targetClass)
上面advised是AdvisedSupport对象(也是ProxyFactoryBean的基类).
getInterceptorsAndDynamicInterceptionAdvice中:
a.从cache中取已有的inceteptor链,第一次要存入.
b.inteceptor链由advisorChainFactory(使用DefaultAdvisorChainFactory)生成1.生成一个List(长度由配置的通知器个数决定).
2.AdvisorAdapterRegistry实现拦截器的注册.
3.注册完成后List中的拦截器会被JDK生成的AopProxy代理对象的invoke()
或者CGLIB代理对象的intercept()
拦截方法取得,最终触发切面增强.
注:getInterceptorsAndDynamicInterceptionAdvice中的advisor是从AdvisorSupport(在ProxyFactoryBean的getObject方法中进行初始化(initalizeAdvisorChain()
))中取得。
在initalizeAdvisorChain方法中如果bean实现了BeanFactoryAware接口,则可以吧IOC容器设置到bean自身的一个属性中去,所以可以在FactoryBean中获得IOC容器。
Advice通知的实现(通知如何实现对目标对象的增强)
a.构造GlobalAdvisorAdapterRegistry (
invoke()
->>getInterceptorsAndDynamicInterceptionAdvice
中)
b.对配置的advisor通知器(在advised参数中)逐个遍历。
c.用a中创建的GlobalAdvisorAdapterRegistry(由该对象创建的DefaultAdvisorAdapterRegistry对完成拦截器适配和注册)。
注:在DefaultAdvisorAdapterRegistry中:
通过一系列的adapter适配器,来对advice提供编织能力
registerAdvisorAdapter(new MethodBeforeAdviceAdapter());
registerAdvisorAdapter(new AfterReturningAdviceAdapter());
registerAdvisorAdapter(new ThrowsAdviceAdapter());
其中adapter的supportAdapter()
取得advice属于什么类型的通知而注册不同的AdviceInterceopter拦截器(这些拦截器实现了不同的通知)。