protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) { if (beanName != null && this.targetSourcedBeans.contains(beanName)) { return bean; } if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) { return bean; } if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) { this.advisedBeans.put(cacheKey, Boolean.FALSE); return bean; } 【1】是否有适合当前Bean的建议者。 Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null); if (specificInterceptors != DO_NOT_PROXY) { this.advisedBeans.put(cacheKey, Boolean.TRUE); 【2】创建代理对象 Object proxy = createProxy( bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean)); this.proxyTypes.put(cacheKey, proxy.getClass()); return proxy; } this.advisedBeans.put(cacheKey, Boolean.FALSE); return bean; }
getAdvicesAndAdvisorsForBean:
- 先执行上文提到的寻找建议者的逻辑,找到当前上下文存在的建议者
- 判断建议者是否给当前Bean提了建议(引介增强会使用类匹配,切点增强会使用切点的MethodMatcher进行匹配),提了建议就创建代理。
2.2.4.代理的创建
有了建议者,有了目标对象,创建代理也就顺理成章。但创建所涉及的功能组件却没有那么简单。
(1)JdkDynamicAopProxy与CglibAopProxy
- JdkDynamicAopProxy:是对JDK动态创建代理的封装,JdkDynamicAopProxy本身就是一个
InvocationHandler
,并提供getProxy
方法,通过反射Proxy
创建代理。 - CglibAopProxy:对CGLB动态代理创建的封装。
getProxy
通过Enhancer+DynamicAdvisedInterceptor
创建代理对象
这两种增强都会有一个AdvisedSupport
属性保存建议者。
private final AdvisedSupport advised;
这两个是底层封装,Spring创建代理并没有直接调用他们,而是封装了三个更高层次的组件
(2)AspectJProxyFactory与ProxyFactoryBean与ProxyFactory
这三个组件都是AdvisedSupport
的子类。
这三个组件都可以用作创建代理对象,他们上没有本质的区别,都是ProxyCreatorSupport
的子类。创建代理对象的逻辑调用也在ProxyCreatorSupport
中。
将多个建议者
告诉ProxyCreatorSupport
,ProxyCreatorSupport会调用策略工厂AopProxyFactory
选择JdkDynamicAopProxy
或者CglibAopProxy
创建代理对象。
protected Object createProxy( Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) { 【1】ProxyFactory组件 ProxyFactory proxyFactory = new ProxyFactory(); proxyFactory.copyFrom(this); 【2】设置建议者 Advisor[] advisors = buildAdvisors(beanName, specificInterceptors); proxyFactory.addAdvisors(advisors); 【3】创建代理对象 return proxyFactory.getProxy(getProxyClassLoader()); }
此时,我们定义的建议者正式与JDK或者CGLB挂上了钩。
可以看出,简简单单的JDK,CGLB代理。Spring 融入此功能时做了多么复杂的设计。
2.2.5.代理的执行
以JDK动态代理为例,执行invoke方法
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { [1] List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass); [2] invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain); [3] // Proceed to the joinpoint through the interceptor chain. retVal = invocation.proceed(); }
- (1)从
AdvisedSupport
获建议者链,此过程通过AdvisorChainFactory
组件完成,将适用于当前目标对象的建议者取出来,创建一个执行建议链。 - (2)根据建议链等信息,创建一个MethodInvocation执行器
- (3)执行得到结果
代理类其实也是实现了
Advied
接口,但是内存生成的那个类,并不会展示Advied接口,但是通过instance of 查看可以查看。
3.总结
AOP之所以复杂,就在于Spring在上层建筑上所做的东西比较多。其本质就是JDK动态代理(Proxy+InvocationHandler)与CGLB(Enhancer + MethodInterceptor(CallBack))
搞清楚SpringAOP组件的角色,以及与底层基础的连接点。理解AOP就不难了。
万层高楼平地起,抓住根 与 主干,就能窥探其奥秘
反过来讲,当我们设计架构时,应该列出我们的核心,围绕核心做上层设计。
第一遍刷
- 静态代理与JDK动态代理与CGLIB动态代理
- spring源码系列8:AOP源码解析之代理的创建
- spring源码系列9:事务代理的创建
- spring源码系列10:AOP代理对象的执行
- spring源码系列11:事务代理对象的执行