Spring框架学习【创建AOP代理对象并对目标对象切面拦截】

1.Spring AOP的底层实现常用类:

分析Spring AOP的底层实现首先要从ProxyConfig类开始,ProxyConfig是所有产生Spring AOP代理对象的基类,它是一个数据类,主要为其AOP代理对象工厂实现类提供配置属性。根据ProxyConfig的继承体系分析创建AOP代理常用类的作用:

(1).AdvisedSupportProxyConfig的子类,它封装了AOP中对通知(Advice)和通知器(Advisor)的相关操作,这些操作对于不同的AOP的代理对象的生成都是一样的,但对于具体的AOP代理对象的创建,AdvisedSupport把它交给子类去实现。

(2).ProxyCreatorSupportAdvisedSupport的子类,它是其子类创建AOP代理对象的一个辅助类,提供不同AOP代理对象生成的通用操作,具体的AOP代理对象生成,由ProxyCreatorSupport的子类完成。

(3).创建AOP代理对象的类:

ProxyCreatorSupport3个子类,分别创建不同的AOP代理对象,具体如下:

a.AspectJProxyFactory:主要用于创建AspectJAOP应用,起到集成SpringAspectJ的作用。

b.ProxyFactory:创建编程式的Spring AOP应用。

c.ProxyFactoryBean:创建声明式的Spring AOP应用。

2.声明式Spring AOP代理工厂对象ProxyFactoryBean

我们以ProxyFactoryBean为例,分析Spring AOP的实现原理,ProxyFactoryBeanSpring中一个非常灵活的创建AOP应用的底层方法,封装了AOP的主要功能。

一个简单的AOP代理工厂对象的配置如下:

[xhtml] view plaincopyprint?
  1. <!--配置通知器,通知器的实现定义了需要对目标对象进行的增强行为-->  
  2. <bean id=”testAdvisor” class=”com.test.TestAdvisor”/>  
  3. <!--配置AOP代理,封装AOP功能的主要类-->  
  4. <bean id=”testAOP” class=”org.springframework.aop.ProxyFactoryBean”>  
  5.     <!--AOP代理接口-->  
  6.     <property name=”proxyInterfaces”>  
  7.         <value>com.test.TestProxyInterface</value>  
  8.     </property>  
  9.     <!--需要使用AOP切面增强的对象-->  
  10.     <property name=”target”>  
  11.         <bean class=”com.test.TestTarget”/>  
  12.     </property>  
  13.     <!--代理拦截器,配置通知器的名称,即通知器在AOP代理的配置下通过使用代理对象的拦截机制发挥作用-->  
  14.     <property name=”interceptorNames”>  
  15.         <list>  
  16.             <value>testAdvisor</value>  
  17.         </list>  
  18.     </property>  
  19. </bean>  

3.ProxyFactoryBean生成AOPProxy代理对象:

2ProxyFactoryBean的简单配置例子我们可以看出,ProxyFactoryBean是用来配置目标对象和切面行为Advice的,ProxyFactoryBean通过其配置的拦截器名称interceptorNames即通知器Advisor将切面行为Advice应用到目标对象中。

ProxyFactoryBean中,需要为待增强目标对象目标对象生成Proxy代理对象,从而为AOP切面的编织提供基础,下面通过源码分析ProxyFactoryBean的生成AOPProxy代理对象的实现过程:

(1).ProxyFactoryBean产生代理对象的主要源码:

[java] view plaincopyprint?
  1. public class ProxyFactoryBean extends ProxyCreatorSupport  
  2.         implements FactoryBean<Object>, BeanClassLoaderAware, BeanFactoryAware {  
  3. //标注通知器器为全局通用通知器   
  4. public static final String GLOBAL_SUFFIX = "*";  
  5. //标志通知器链是否已经完成初始化   
  6. private boolean advisorChainInitialized = false;  
  7. //单态模式对象   
  8. private Object singletonInstance;  
  9. ……  
  10. //ProxyFactoryBean创建AOPProxy代理的入口方法   
  11. public Object getObject() throws BeansException {  
  12.         //初始化通知器链   
  13.         initializeAdvisorChain();  
  14.         //如果目标对象是单态模式   
  15.         if (isSingleton()) {  
  16.             //调用获取单态模式对象的方法产生AOPProxy代理   
  17.             return getSingletonInstance();  
  18.         }  
  19.         //如果目标对象是原型模式   
  20.         else {  
  21.             if (this.targetName == null) {  
  22.                 logger.warn("Using non-singleton proxies with singleton targets is often undesirable. " +  
  23.                         "Enable prototype proxies by setting the ‘targetName‘ property.");  
  24.             }  
  25.             //调用原型模式对象方法每次创建一个新的AOPProxy代理对象   
  26.             return newPrototypeInstance();  
  27.         }  
  28.     }  
  29. //初始化通知器链   
  30. private synchronized void initializeAdvisorChain() throws AopConfigException, BeansException {  
  31.     //如果通知器链已经被初始化,则直接返回,即通知器链只在第一次获取代理对象时产生   
  32.         if (this.advisorChainInitialized) {  
  33.             return;  
  34.         }  
  35.         //如果ProxyFactoryBean中配置的连接器列名名称不为空   
  36.         if (!ObjectUtils.isEmpty(this.interceptorNames)) {  
  37.             //如果没有Bean工厂(容器)   
  38.             if (this.beanFactory == null) {  
  39.                 throw new IllegalStateException("No BeanFactory available anymore (probably due to serialization) " +  
  40.                         "- cannot resolve interceptor names " + Arrays.asList(this.interceptorNames));  
  41.             }  
  42.             //全局通知器不能是通知器链中最后一个,除非显式使用属性指定了目标   
  43.             if (this.interceptorNames[this.interceptorNames.length - 1].endsWith(GLOBAL_SUFFIX) &&  
  44.                     this.targetName == null && this.targetSource == EMPTY_TARGET_SOURCE) {  
  45.                 throw new AopConfigException("Target required after globals");  
  46.             }  
  47.             //遍历通知器链,向容器添加通知器   
  48.             for (String name : this.interceptorNames) {  
  49.                 if (logger.isTraceEnabled()) {  
  50.                     logger.trace("Configuring advisor or advice ‘" + name + "‘");  
  51.                 }  
  52.                 //如果通知器是全局的   
  53.                 if (name.endsWith(GLOBAL_SUFFIX)) {  
  54.                     if (!(this.beanFactory instanceof ListableBeanFactory)) {  
  55.                         throw new AopConfigException(  
  56.                                 "Can only use global advisors or interceptors with a ListableBeanFactory");  
  57.                     }  
  58.                     //向容器中添加全局通知器   
  59.                     addGlobalAdvisor((ListableBeanFactory) this.beanFactory,  
  60.                             name.substring(0, name.length() - GLOBAL_SUFFIX.length()));  
  61.                 }  
  62.                 //如果通知器不是全局的   
  63.                 else {  
  64.                     Object advice;  
  65.                     //如果通知器是单态模式   
  66.                     if (this.singleton || this.beanFactory.isSingleton(name)) {  
  67.                         //从容器获取单态模式的通知或者通知器   
  68.                         advice = this.beanFactory.getBean(name);  
  69.                     }  
  70.                     //如果通知器是原型模式   
  71.                     else {  
  72.                         //创建一个新的通知或者通知器对象   
  73.                         advice = new PrototypePlaceholderAdvisor(name);  
  74.                     }  
  75.                     //添加通知器   
  76.                     addAdvisorOnChainCreation(advice, name);  
  77.                 }  
  78.             }  
  79.         }  
  80.         //设置通知器链已初始化标识   
  81.         this.advisorChainInitialized = true;  
  82.     }  
  83. //获取一个单态模式的AOPProxy代理对象   
  84. private synchronized Object getSingletonInstance() {  
  85.         //如果单态模式的代理对象还未被创建   
  86.         if (this.singletonInstance == null) {  
  87.             //获取代理的目标源   
  88.             this.targetSource = freshTargetSource();  
  89.             //如果ProxyFactoryBean设置了自动探测接口属性,并且没有配置代理接   
  90.             //且不是目标对象的直接代理类   
  91.             if (this.autodetectInterfaces && getProxiedInterfaces().length == 0 && !isProxyTargetClass()) {  
  92.                 //获取代理对象的目标类   
  93.                 Class targetClass = getTargetClass();  
  94.                 if (targetClass == null) {  
  95.                     throw new FactoryBeanNotInitializedException("Cannot determine target class for proxy");  
  96.                 }  
  97.             //设置代理对象的接口 setInterfaces(ClassUtils.getAllInterfacesForClass(targetClass, this.proxyClassLoader));   
  98.             }  
  99.     //初始化共享的单态模式对象                   super.setFrozen(this.freezeProxy);   
  100.     //调用ProxyFactory生成代理AOPProxy对象   
  101.             this.singletonInstance = getProxy(createAopProxy());  
  102.         }  
  103.         return this.singletonInstance;  
  104.     }  
  105. //获取一个原型模式的代理对象   
  106. private synchronized Object newPrototypeInstance() {  
  107.         if (logger.isTraceEnabled()) {  
  108.             logger.trace("Creating copy of prototype ProxyFactoryBean config: " + this);  
  109.         }  
  110.         //根据当前的AOPProxyFactory获取一个创建代理的辅助类   
  111.         ProxyCreatorSupport copy = new ProxyCreatorSupport(getAopProxyFactory());  
  112.         //获取一个刷新的目标源   
  113.         TargetSource targetSource = freshTargetSource();  
  114.         //从当前对象中拷贝AOP的配置,为了保持原型模式对象的独立性,每次创建代理   
  115. //对象时都需要拷贝AOP的配置,以保证原型模式AOPProxy代理对象的独立性   
  116.         copy.copyConfigurationFrom(this, targetSource, freshAdvisorChain());  
  117.         if (this.autodetectInterfaces && getProxiedInterfaces().length == 0 && !isProxyTargetClass()) {  
  118.             //设置代理接口   
  119.             copy.setInterfaces(  
  120.     ClassUtils.getAllInterfacesForClass(targetSource.getTargetClass(), this.proxyClassLoader));  
  121.         }  
  122.         copy.setFrozen(this.freezeProxy);  
  123.         if (logger.isTraceEnabled()) {  
  124.             logger.trace("Using ProxyCreatorSupport copy: " + copy);  
  125.         }  
  126.         //调用ProxyFactory生成AOPProxy代理   
  127.         return getProxy(copy.createAopProxy());  
  128.     }  
  129. //使用createAopProxy方法返回的AOPProxy对象产生AOPProxy代理对象   
  130. protected Object getProxy(AopProxy aopProxy) {  
  131.         return aopProxy.getProxy(this.proxyClassLoader);  
  132.     }  
  133. ……  
  134. }  

通过源码分析,我们了解到AOPProxyFactory实现了FactoryBean接口,所以本身也是一个Spring的工厂BeanAOP代理工厂的主要功能概况为:

a.初始化通知器链,将配置的通知器链添加到容器存放通知/通知器的集合中。

b.根据单态模式/原型模式,获取AOPProxy产生AOPProxy代理对象。

(2).AOP创建辅助器(AOPCreatorSupport)获取AOPProxy代理对象:

AOPProxyFactorygetSingletonInstancenewPrototypeInstance方法均通过调用AOPCreatorSupportcreateAopProxy()方法获取AOPProxy,主要源码如下:

[java] view plaincopyprint?
  1. public class ProxyCreatorSupport extends AdvisedSupport {  
  2. //AOPProxy工厂   
  3. private AopProxyFactory aopProxyFactory;  
  4. //当第一个AOPProxy代理对象被创建时,设置为true   
  5. private boolean active = false;  
  6. public AopProxyFactory getAopProxyFactory() {  
  7.         return this.aopProxyFactory;  
  8.     }  
  9. //默认使用DefaultAopProxyFactory作用AOP代理工厂   
  10. public ProxyCreatorSupport() {  
  11.         this.aopProxyFactory = new DefaultAopProxyFactory();  
  12.     }  
  13. //创建AOPProxy代理的入口方法   
  14. protected final synchronized AopProxy createAopProxy() {  
  15.         if (!this.active) {  
  16.             activate();  
  17.         }  
  18.         //调用DefaultAopProxyFactory的创建AOPProxy代理的方法   
  19.         return getAopProxyFactory().createAopProxy(this);  
  20.     }   
  21. //激活AOP代理配置,向容器注册代理回调监听器,第一次创建AOP代理时调用   
  22. private void activate() {  
  23.         this.active = true;  
  24.         for (AdvisedSupportListener listener : this.listeners) {  
  25.             listener.activated(this);  
  26.         }  
  27.     }   
  28. ……  
  29. }  

通过对ProxyCreatorSupport的源码分析,我们知道真正创建AOPProxy代理对象的是DefaultAopProxyFactory类。

(3).DefaultAopProxyFactory创建AOPProxy代理对象:

DefaultAopProxyFactoryAOP创建辅助器(AOPCreatorSupport)默认的AOP代理工厂,DefaultAopProxyFactorycreateAopProxy方法实现了创建AOP代理的功能,源码如下:

[java] view plaincopyprint?
  1. public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {  
  2. //判断CGLIB类库是否在classpath中   
  3. private static final boolean cglibAvailable =  
  4.             ClassUtils.isPresent("net.sf.cglib.proxy.Enhancer", DefaultAopProxyFactory.class.getClassLoader());  
  5. //创建AOP代理对象   
  6. public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {  
  7.         //如果AOP使用显式优化,或者配置了目标类,或者只使用Spring支持的代理接口   
  8.         if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {  
  9.             //获取AOP配置的目标类   
  10.             Class targetClass = config.getTargetClass();  
  11.             if (targetClass == null) {  
  12.                 throw new AopConfigException("TargetSource cannot determine target class: " +  
  13.                         "Either an interface or a target is required for proxy creation.");  
  14.             }  
  15.             //如果配置的AOP目标类是接口,则使用JDK动态代理机制来生成AOP代理   
  16.             if (targetClass.isInterface()) {  
  17.                 return new JdkDynamicAopProxy(config);  
  18.             }  
  19.             //如果AOP配置的目标类不是接口,则使用CGLIB的方式来生成AOP代理   
  20.             if (!cglibAvailable) {  
  21.                 throw new AopConfigException(  
  22.                         "Cannot proxy target class because CGLIB2 is not available. " +  
  23.                         "Add CGLIB to the class path or specify proxy interfaces.");  
  24.             }  
  25.             return CglibProxyFactory.createCglibProxy(config);  
  26.         }  
  27.         else {  
  28.             return new JdkDynamicAopProxy(config);  
  29.         }  
  30.     }  
  31. //判断AOP是否只配置了SpringProxy代理接口或者没有配置任何代理接口   
  32.     private boolean hasNoUserSuppliedProxyInterfaces(AdvisedSupport config) {  
  33.         //获取AOP配置的所有AOP代理接口   
  34.         Class[] interfaces = config.getProxiedInterfaces();  
  35.         return (interfaces.length == 0 || (interfaces.length == 1 && SpringProxy.class.equals(interfaces[0])));  
  36.     }  
  37. }  

通过对DefaultAopProxyFactory的源码分析,我们了解了Spring在创建AOP代理对象时,如果配置的目标类是接口,则使用JDK的动态代理机制来生成AOP代理,如果使用的不是接口,则使用CGLIB方式来生成AOP的动态代理。

4.JDK动态代理机制创建AOPProxy代理对象:

JDK的动态代理机制只能对接口起作用,即如果要对一个对象使用JDK动态代理方式生成代理对象时,该对象必须实现接口,Spring中通过JdkDynamicAopProxy类使用JDK动态代理机制生成AOPProxy代理对象,JdkDynamicAopProxy的主要源码如下:

[java] view plaincopyprint?
  1. final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable {  
  2. ……  
  3. //JdkDynamicAopProxy的构造方法   
  4.     public JdkDynamicAopProxy(AdvisedSupport config) throws AopConfigException {  
  5.         Assert.notNull(config, "AdvisedSupport must not be null");  
  6.         //获取AOPBeanFactory中配置的通知器链和目标源   
  7.         if (config.getAdvisors().length == 0 && config.getTargetSource() == AdvisedSupport.EMPTY_TARGET_SOURCE) {  
  8.             throw new AopConfigException("No advisors and no TargetSource specified");  
  9.         }  
  10.         //为当前对象设置AOP配置   
  11.         this.advised = config;  
  12.     }  
  13.     //获取AOP代理对象的入口方法   
  14.     public Object getProxy() {  
  15.         return getProxy(ClassUtils.getDefaultClassLoader());  
  16.     }  
  17.     //创建AOP代理对象   
  18.     public Object getProxy(ClassLoader classLoader) {  
  19.         if (logger.isDebugEnabled()) {  
  20.             logger.debug("Creating JDK dynamic proxy: target source is " + this.advised.getTargetSource());  
  21.         }  
  22.         //获取AOPBeanFactory中配置的代理接口   
  23.         Class[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised);  
  24.         //查找代理目标的接口中是否定义equals()和hashCode()方法   
  25.         findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);  
  26.         //使用JDK的动态代理机制创建AOP代理对象   
  27.         return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);  
  28.     }  
  29.     //查找给定类或接口中是否定义了equals()和hashCode()方法   
  30.     private void findDefinedEqualsAndHashCodeMethods(Class[] proxiedInterfaces) {  
  31.         //遍历给定的类/接口数组   
  32.         for (Class proxiedInterface : proxiedInterfaces) {  
  33.             //或者给定类/接口中所有声明的方法   
  34.             Method[] methods = proxiedInterface.getDeclaredMethods();  
  35.             //遍历类/接口中的声明的方法   
  36.             for (Method method : methods) {  
  37.                 //如果方法是equals()方法,则设置当前对象equalsDefined属性   
  38.                 if (AopUtils.isEqualsMethod(method)) {  
  39.                     this.equalsDefined = true;  
  40.                 }  
  41. //如果方法是hashCode()方法,则设置当前对象hashCodeDefined属性   
  42.                 if (AopUtils.isHashCodeMethod(method)) {  
  43.                     this.hashCodeDefined = true;  
  44.                 }  
  45.                 if (this.equalsDefined && this.hashCodeDefined) {  
  46.                     return;  
  47.                 }  
  48.             }  
  49.         }  
  50.     }  
  51. //AOP代理对象的回调方法   
  52.     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {  
  53.         MethodInvocation invocation;  
  54.         Object oldProxy = null;  
  55.         boolean setProxyContext = false;  
  56.         //获取通知的目标源   
  57.         TargetSource targetSource = this.advised.targetSource;  
  58.         Class targetClass = null;  
  59.         Object target = null;  
  60.         try {  
  61.             //如果代理目标对象的接口中没有定义equals()方法,且当前调用的方法   
  62. //是equals()方法,即目标对象没有自己实现equals()方法   
  63.             if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {  
  64.                 return equals(args[0]);  
  65.             }  
  66.             //如果代理目标对象的接口中没有定义hashCode()方法,且当前调用的方法   
  67. //是hashCode()方法,即目标对象没有自己实现hashCode()方法   
  68.             if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {  
  69.                 return hashCode();  
  70.             }  
  71.             //如果AOP配置了通知,使用反射机制调用通知的同名方法   
  72.             if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&             method.getDeclaringClass().isAssignableFrom(Advised.class)) {  
  73.                 return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);  
  74.             }  
  75.             Object retVal;  
  76.         //如果当前通知暴露了代理,则将当前代理使用currentProxy()方法变为可用代理   
  77.             if (this.advised.exposeProxy) {  
  78.                 oldProxy = AopContext.setCurrentProxy(proxy);  
  79.                 setProxyContext = true;  
  80.             }  
  81.             //获取目标对象   
  82.             target = targetSource.getTarget();  
  83.             if (target != null) {  
  84.                 targetClass = target.getClass();  
  85.             }  
  86.             //获取目标对象方法配置的拦截器(通知器)链   
  87.             List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);  
  88.             //如果没有配置任何通知   
  89.             if (chain.isEmpty()) {  
  90.                 //没有配置通知,使用反射直接调用目标对象的方法,并获取方法返回值   
  91.                 retVal = AopUtils.invokeJoinpointUsingReflection(target, method, args);  
  92.             }  
  93.             //如果配置了通知   
  94.             else {  
  95.             //为目标对象创建方法回调对象,需要在调用通知之后才调用目标对象的方法   
  96.                 invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);  
  97.                 //调用通知链,沿着通知器链调用所有配置的通知   
  98.                 retVal = invocation.proceed();  
  99.             }  
  100.             //如果方法有返回值,则将代理对象最为方法返回   
  101.             if (retVal != null && retVal == target && method.getReturnType().isInstance(proxy) &&  
  102.                     !RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {  
  103.                 retVal = proxy;  
  104.             }  
  105.             return retVal;  
  106.         }  
  107.         finally {  
  108.             if (target != null && !targetSource.isStatic()) {  
  109.                 //释放目标对象   
  110.                 targetSource.releaseTarget(target);  
  111.             }  
  112.             if (setProxyContext) {  
  113.                 //存储代理对象   
  114.                 AopContext.setCurrentProxy(oldProxy);  
  115.             }  
  116.         }  
  117.     }  
  118. ……  
  119. }  

通过上述源码分析,我们看到JdkDynamicAopProxy本身实现了InvocationHandler接口和invoke()方法,JDK的动态代理机制的工作原理是:当调用目标对象的方法时,不是直接调用目标对象,而是首先生成一个目标对象的动态代理对象,触发代理对象的invoke()方法,代理的invoke()方法才会真正调用目标对象的方法。Spring AOP的实现原理是在代理对象invoke()方法调用目标对象的方法时,调用配置的通知。

5.CglibProxyFactory创建AOPProxy代理

JDK的动态代理只能针对接口生成代理对象,对于没有实现接口的目标对象,必须通过第3方的CGLIB来生成代理对象,CglibProxyFactory创建AOPProxy代理的主要源码如下:

[java] view plaincopyprint?
  1. //通过CGLIB方式创建AOP代理对象   
  2. public Object getProxy(ClassLoader classLoader) {  
  3.         if (logger.isDebugEnabled()) {  
  4.             logger.debug("Creating CGLIB2 proxy: target source is " + this.advised.getTargetSource());  
  5.         }  
  6.         try {  
  7.             //从代理创建辅助类中获取在IoC容器中配置的目标对象   
  8.             Class rootClass = this.advised.getTargetClass();  
  9.             Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");  
  10.             //将目标对象本身做为自己的基类   
  11.             Class proxySuperClass = rootClass;  
  12.             //检查获取到的目标类是否是CGLIB产生的   
  13.             if (AopUtils.isCglibProxyClass(rootClass)) {  
  14.                 //如果目标类是有CGLIB产生的,获取目标类的基类   
  15.                 proxySuperClass = rootClass.getSuperclass();  
  16.                 //获取目标类的接口   
  17.                 Class[] additionalInterfaces = rootClass.getInterfaces();  
  18.                 //将目标类的接口添加到容器AOP代理创建辅助类的配置中   
  19.                 for (Class additionalInterface : additionalInterfaces) {  
  20.                     this.advised.addInterface(additionalInterface);  
  21.                 }  
  22.             }  
  23.             //校验代理基类   
  24.             validateClassIfNecessary(proxySuperClass);  
  25.             //配置CGLIB的Enhancer类,Enhancer是CGLIB中的主要操作类   
  26.             Enhancer enhancer = createEnhancer();  
  27.             if (classLoader != null) {  
  28.                 enhancer.setClassLoader(classLoader);  
  29.                 if (classLoader instanceof SmartClassLoader &&  
  30.                         ((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {  
  31.                     enhancer.setUseCache(false);  
  32.                 }  
  33.             }  
  34.             //设置enhancer的基类   
  35.             enhancer.setSuperclass(proxySuperClass);  
  36.             enhancer.setStrategy(new UndeclaredThrowableStrategy(UndeclaredThrowableException.class));  
  37.     //设置enhancer的接口 enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));   
  38.             enhancer.setInterceptDuringConstruction(false);  
  39.             //设置enhancer的回调方法   
  40.             Callback[] callbacks = getCallbacks(rootClass);  
  41.             enhancer.setCallbacks(callbacks);  
  42.             //将通知器中配置作为enhancer的方法过滤   
  43.             enhancer.setCallbackFilter(new ProxyCallbackFilter(  
  44.                     this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));  
  45.             Class[] types = new Class[callbacks.length];  
  46.             for (int x = 0; x < types.length; x++) {  
  47.                 types[x] = callbacks[x].getClass();  
  48.             }  
  49.             //设置enhancer的回调类型   
  50.             enhancer.setCallbackTypes(types);  
  51.             //创建代理对象   
  52.             Object proxy;  
  53.             if (this.constructorArgs != null) {  
  54.                 proxy = enhancer.create(this.constructorArgTypes, this.constructorArgs);  
  55.             }  
  56.             else {  
  57.                 proxy = enhancer.create();  
  58.             }  
  59.             return proxy;  
  60.         }  
  61.         catch (CodeGenerationException ex) {  
  62.             throw new AopConfigException("Could not generate CGLIB subclass of class [" +  
  63.                     this.advised.getTargetClass() + "]: " +  
  64.                     "Common causes of this problem include using a final class or a non-visible class",  
  65.                     ex);  
  66.         }  
  67.         catch (IllegalArgumentException ex) {  
  68.             throw new AopConfigException("Could not generate CGLIB subclass of class [" +  
  69.                     this.advised.getTargetClass() + "]: " +  
  70.                     "Common causes of this problem include using a final class or a non-visible class",  
  71.                     ex);  
  72.         }  
  73.         catch (Exception ex) {  
  74.             // TargetSource.getTarget() failed   
  75.             throw new AopConfigException("Unexpected AOP exception", ex);  
  76.         }  
  77.     }  
  78. //获取给定类的回调通知   
  79.  private Callback[] getCallbacks(Class rootClass) throws Exception {  
  80.         //优化参数   
  81.         boolean exposeProxy = this.advised.isExposeProxy();  
  82.         boolean isFrozen = this.advised.isFrozen();  
  83.         boolean isStatic = this.advised.getTargetSource().isStatic();  
  84.         //根据AOP配置创建一个动态通知拦截器,CGLIB创建的动态代理会自动调用   
  85.         //DynamicAdvisedInterceptor类的intercept方法对目标对象进行拦截处理   
  86.         Callback aopInterceptor = new DynamicAdvisedInterceptor(this.advised);  
  87.         Callback targetInterceptor;  
  88.         //根据是否暴露代理,创建直接应用目标的通知   
  89.         if (exposeProxy) {  
  90.             targetInterceptor = isStatic ?  
  91.                     new StaticUnadvisedExposedInterceptor(this.advised.getTargetSource().getTarget()) :  
  92.                     new DynamicUnadvisedExposedInterceptor(this.advised.getTargetSource());  
  93.         }  
  94.         else {  
  95.             targetInterceptor = isStatic ?  
  96.                     new StaticUnadvisedInterceptor(this.advised.getTargetSource().getTarget()) :  
  97.                     new DynamicUnadvisedInterceptor(this.advised.getTargetSource());  
  98.         }  
  99.         // 创建目标分发器   
  100.         Callback targetDispatcher = isStatic ?  
  101.                 new StaticDispatcher(this.advised.getTargetSource().getTarget()) : new SerializableNoOp();  
  102.         Callback[] mainCallbacks = new Callback[]{  
  103.             aopInterceptor, //普通通知   
  104.             targetInterceptor, // 如果优化则不考虑配置的通知   
  105.             new SerializableNoOp(), //没有被覆盖的方法   
  106.             targetDispatcher, this.advisedDispatcher,  
  107.             new EqualsInterceptor(this.advised),  
  108.             new HashCodeInterceptor(this.advised)  
  109.         };  
  110.         Callback[] callbacks;  
  111.         //如果目标是静态的,并且通知链被冻结,则使用优化AOP调用,直接对方法使用   
  112. //固定的通知链   
  113.         if (isStatic && isFrozen) {  
  114.             Method[] methods = rootClass.getMethods();  
  115.             Callback[] fixedCallbacks = new Callback[methods.length];  
  116.             this.fixedInterceptorMap = new HashMap<String, Integer>(methods.length);  
  117.             for (int x = 0; x < methods.length; x++) {  
  118.                 List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(methods[x], rootClass);  
  119.                 fixedCallbacks[x] = new FixedChainStaticTargetInterceptor(  
  120.                         chain, this.advised.getTargetSource().getTarget(), this.advised.getTargetClass());  
  121.                 this.fixedInterceptorMap.put(methods[x].toString(), x);  
  122.             }  
  123.             //将固定回调和主要回调拷贝到回调数组中   
  124.             callbacks = new Callback[mainCallbacks.length + fixedCallbacks.length];  
  125.             System.arraycopy(mainCallbacks, 0, callbacks, 0, mainCallbacks.length);  
  126.             System.arraycopy(fixedCallbacks, 0, callbacks, mainCallbacks.length, fixedCallbacks.length);  
  127.             this.fixedInterceptorOffset = mainCallbacks.length;  
  128.         }  
  129.         //如果目标不是静态的,或者通知链不被冻结,则使用AOP主要的通知   
  130.         else {  
  131.             callbacks = mainCallbacks;  
  132.         }  
  133.         return callbacks;  
  134.     }  

通过上面对CGLIB创建代理和获取回答通知的源码分析,我们了解到CGLIB在获取代理的通知时,会创建DynamicAdvisedInterceptor类,当应用调用目标对象的方法时,不是直接调用目标对象,而是通过CGLIB创建的代理对象来调用目标对象,在调用目标对象的方法时,触发DynamicAdvisedInterceptorintercept回调方法对目标对象进行处理,CGLIB回调拦截器链的源码如下:

[java] view plaincopyprint?
  1. //CGLIB回调AOP拦截器链   
  2. public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {  
  3.             Object oldProxy = null;  
  4.             boolean setProxyContext = false;  
  5.             Class targetClass = null;  
  6.             Object target = null;  
  7.             try {  
  8.                 //如果通知器暴露了代理   
  9.                 if (this.advised.exposeProxy) {  
  10.                     //设置给定的代理对象为要被拦截的代理                                          oldProxy = AopContext.setCurrentProxy(proxy);   
  11.                     setProxyContext = true;  
  12.                 }  
  13.                 //获取目标对象   
  14.                 target = getTarget();  
  15.                 if (target != null) {  
  16.                     targetClass = target.getClass();  
  17.                 }  
  18.                 //获取AOP配置的通知   
  19.                 List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);  
  20.                 Object retVal;  
  21.                 //如果没有配置通知   
  22.                 if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {  
  23.                     //直接调用目标对象的方法   
  24.                     retVal = methodProxy.invoke(target, args);  
  25.                 }  
  26.                 //如果配置了通知   
  27.                 else {  
  28.                     //通过CglibMethodInvocation来启动配置的通知   
  29.                     retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();  
  30.                 }  
  31.                 //获取目标对象对象方法的回调结果,如果有必要则封装为代理   
  32.                 retVal = massageReturnTypeIfNecessary(proxy, target, method, retVal);  
  33.                 return retVal;  
  34.             }  
  35.             finally {  
  36.                 if (target != null) {  
  37.                     releaseTarget(target);  
  38.                 }  
  39.                 if (setProxyContext) {  
  40.                     //存储被回调的代理   
  41.                     AopContext.setCurrentProxy(oldProxy);  
  42.                 }  
  43.             }  
  44.         }  

6.目标对象方法的调用:

通过上面45分别对JdkDynamicAopProxyCglib2AopProxy创建AOPProxy代理对象,以及对目标对象的通知器回调我们可以看出,当目标对象没有配置通知器时,代理对象直接调用目标对象的方法,下面具体分析直接调用目标对象方法的过程:

(1).JdkDynamicAopProxy直接调用目标对象方法:

JdkDynamicAopProxy中是通过AopUtils.invokeJoinpointUsingReflection方法来直接调用目标对象的方法,源码如下:

[java] view plaincopyprint?
  1. //通过反射机制直接调用目标对象方法   
  2. public static Object invokeJoinpointUsingReflection(Object target, Method method, Object[] args)  
  3.             throws Throwable {  
  4.         try {  
  5. //通过反射使给定的方法可以访问,主要是对protected和private方法使用,//取消严格访问控制权限的限制   
  6.             ReflectionUtils.makeAccessible(method);  
  7.             //使用反射机制调用目标对象的方法   
  8.             return method.invoke(target, args);  
  9.         }  
  10.         catch (InvocationTargetException ex) {  
  11.             throw ex.getTargetException();  
  12.         }  
  13.         catch (IllegalArgumentException ex) {  
  14.             throw new AopInvocationException("AOP configuration seems to be invalid: tried calling method [" +  
  15.                     method + "] on target [" + target + "]", ex);  
  16.         }  
  17.         catch (IllegalAccessException ex) {  
  18.             throw new AopInvocationException("Could not access method [" + method + "]", ex);  
  19.         }  
  20.     }  

(2).Cglib2AopProxy直接调用目标对象方法:

Cglib2AopProxy是通过methodProxy.invoke来直接调用目标对象的方法,主要源码如下:

[java] view plaincopyprint?
  1. retVal = methodProxy.invoke(target, args);  

methodProxyCGLIBMethodProxy类的对象,因为我对CGLIB也不熟悉,这里不做深入了解。

7.AOP拦截器链的调用:

通过上面45分别对JdkDynamicAopProxyCglib2AopProxy创建AOPProxy代理对象,以及对目标对象的通知器回调我们了解到,当目标对象配置了通知器时,在对目标对象方法调用前首先需要回调通知器链,JdkDynamicAopProxyCglib2AopProxy都是通过将目标对象方法、方法参数、和通知器链、代理对象等封装为ReflectiveMethodInvocation类,然后通过ReflectiveMethodInvocation.proceed()方法调用通知器链,proceed方法源码如下:

[java] view plaincopyprint?
  1. //通用通知器链   
  2. public Object proceed() throws Throwable {  
  3.         //如果拦截器链中通知已经调用完毕   
  4.         if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {  
  5.             //这个方法调用AopUtils.invokeJoinpointUsingReflection方法,   
  6. //通过反射机制直接调用目标对象方法   
  7.             return invokeJoinpoint();  
  8.         }  
  9.         //获取拦截器链中的通知器或通知   
  10.         Object interceptorOrInterceptionAdvice =        this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);  
  11.         //如果获取的通知器或通知是动态匹配方法拦截器类型   
  12.         if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {  
  13.             //动态匹配方法拦截器   
  14.             InterceptorAndDynamicMethodMatcher dm =  
  15.                 (InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;  
  16.             if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {  
  17.                 //如果匹配,调用拦截器的方法   
  18.                 return dm.interceptor.invoke(this);  
  19.             }  
  20.             else {  
  21.                 //如果不匹配,递归调用proceed()方法,知道拦截器链被全部调用为止   
  22.                 return proceed();  
  23.             }  
  24.         }  
  25.         else {  
  26.             //如果不是动态匹配方法拦截器,则切入点在构造对象之前进行静态匹配,调用   
  27.             //拦截器的方法   
  28.             return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);  
  29.         }  
  30.     }  

Spring框架学习【创建AOP代理对象并对目标对象切面拦截】

上一篇:Android设计模式—建造者模式builder


下一篇:Spring框架学习【AOP通知以及编程式AOP 】