spring技术内幕8-创建AOP代理对象并对目标对象切面拦截

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

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

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

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

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

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

a、AspectJProxyFactory:主要用于创建AspectJ的AOP应用,起到集成Spring和AspectJ的作用。

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

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

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

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

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

<!-- 配置通知器,通知器的实现定义了需要对目标对象进行的增强行为  -->

<bean id="testAdvisor" class = "com.test.TestAdvisor"/>

<!-- 配置AOP代理,封装AOP功能的主要类 -->

<bean id= "testAOP" class = "org.springframework.aop.ProxyFactoryBean">

     <!-- AOP代理接口 -->

     <property name="proxyInterface">

              <value>com.test.TestProxyInterface</value>

     </proerty>

    <!-- 需要使用AOP切面增强的对象 -->

    <property name="target">

             <bean class = "com.test.TestTarget"/>

    </property>

    <!-- 代理拦截器,配置通知器的名称,即通知器在AOP代理的配置下通过使用代理对象的拦截机制发挥作用-->

    <property name="inerceptorNames">

           <list>

                 <value>testAdvisor</value>

           </list>

     </property>

</bean>

3、ProxyFactoryBean生成AOPProxy代理对象:

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

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

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

public class ProxyFactoryBean extends ProxyCreatorSupport implements FactoryBean<Object>,BeanClassLoaderAware,BeanFactoryAware{

   //标记通知器为全局通用通知器

    public static final String GLOBAL_SUFFIX = "*";

  //标记通知器链是否已经完成初始化

    private boolean advisorChainInitialized = false;

   //单态模式对象

    private Object singletonInstance;

 ......

//ProxyFactoryBean创建AOPProxy代理的入口方法

public Object getObject() throws BeansException {

       //初始化通知器链

       initializeAdvisorChain();

      //如果目标对象是单态模式

       if(isSingleton()){

           //调用获取单态模式对象的方法产生AOPProxy代理

            return getSingletonInstance();

        }

       //如果目标对象时原型模式

       else{

           if(this.targetName == null){

                  logger.warn("Using non-singleton proxies with singleton targets is often undesirable." + "Enable prototype proxies by setting the 'targetName' proerty.");

            }

       //调用原型模式对象方法每次创建一个新的AOPProxy代理对象

         return newPrototypeInstance();

      }

 }

//初始化通知器链

private synchronized void initializeAdvisorChain() throws AopConfigException,BeansException {

      //如果通知器链已经被初始化,则直接返回,即通知器链只在第一次获取代理对象时产生

      if(this.advisorChainInitialized){

            return;

       }

     //如果ProxyFactoryBean中配置的连接器列名名称不为空

       if(!ObjectUtils.isEmpty(this.interceptorNames)){

               //如果没有bean工厂(容器)

               if(this.beanFactory == null){

                    throw new IllegalStateException("No BeanFactory available anymor (probably due to serialization)" +

                      " - cannot resolve interceptro names " + Arrays.asList(this.interceptorNames));

               }

               //全局通知器不能使通知器链中最后一个,除非显示使用属性指定了目标

                if(this.interceptorNames[this.interceptorNames.length -1].endsWith(GLOBAL_SUFFIX) && this.targetName == null && this.targetSource == EMPTY_TARGET_SOURCE){

                    throw new AopConfigException("Target required after globals");

                }

               //遍历通知器链,向容器添加通知器

                for(String name : this.interceptorNames){

                     if(logger.isTraceEnabled()){

                        logger.trace("Configuring advisor or advice '" + name + "'");

                     }

                    //如果通知器是全局的

                    if(name.endsWith(GLOBAL_SUFFIX)){

                        if(!(this.beanFactory instanceof ListableBeanFactory)){

                           throw new AopConfigException("Can only use global advisors or interceptors with a ListableBeanFactory");

                        }

                        //向容器中添加全局通知器

                          addGlobalAdvisor((ListableBeanFactory)this.beanFactory,name.substring(0,name.length()-GLOBAL_SUFFIX.length()));

                   }

                   //如果通知器不是全局的

                    else{

                         Object advice;

                         //如果通知器是单态模式

                          if(this.singleton || this.beanFactory.isSingleton(name)){

                                 //从容器获取单态模式的通知或者通知器

                                    advice = this.beanFactory.getBean(name);

                           }

                           //如果通知器是原型模式

                           else{

                                //创建一个新的通知或者通知器对象

                                  advice = new PrototypePlaceholderAdvisor(name);

                           }

                           //添加通知器

                      }

                 }

             }

             //设置通知器链已初始化标识

              this.advisorChainInitialized = true;

   }

//获取一个单态模式的AOPProxy代理对象

private synchronized Object getSingletonInstance(){

       //如果单态模式的代理对象还未被创建

        if(this.singletonInstance == null){

            //获取代理的目标源

               this.targetSource = freshTargetSource();

               //如果ProxyFactoryBean设置了自动探测接口属性,并且没有配置代理接口,且不是目标对象的直接代理类

                if(this.autodetectInterfaces && getProiedInterfaces().length == 0 && !isProxyTargetClass()){

                      //获取代理对象的目标类

                       Class targetClass = getTargetClass();

                       if(targetClass == null){

                           throw new FactoryBeanNotInitializedException("Cannot determine target class for proxy");

                        }

                     //设置代理对象的接口

                      setInterfaces(ClassUtils.getAllInterfacesForClass(targetClass,this.proxyClassLoader));

                  }

                  //初始化共享的单态模式对象

                    super.setFrozen(this.freezeProxy);

                 //调用ProxyFactory生成代理AOPProxy对象

                    this.singletonInstance = getProxy(createAopProxy());

               }

               return this.singletonInstance;

        }

//获取一个原型模式的代理对象

private synchronized Object newPrototypeInstance(){

         if(logger.isTraceEnabled()){

               logger.trace("Creating copy of protorype ProxyFactoryBean config:" + this);

          }

        //根据当前的AOPProxyFactory获取一个创建代理的辅助类

          ProxyCreatorSupport copy = new ProxyCreatorSupport(getAopProxyFactory());

       //获取一个刷新的目标源

         TargetSource targetSource = freshTargetSource();

       //从当前对象中拷贝AOP的配置,为了保持原型模式对象的独立性,每次创建代理对象时都需要拷贝AOP的配置,以保证原型模式AOPProxy代理对象的独立性

          copy.copyConfigurationFrom(this,targetSource,freshAdvisorChain());

          if(this.autodetectInterfaces && getProxiedInterfaces().length == 0 && !isProxyTargetClass()){

               //设置代理接口

               copy.setInterfaces(ClassUtils.getAllInterfacesForClass(targetSource.getTargetClass(),this.proxyClassLoader));

          }

          copy.setFrozen(this.freezeProxy);

          if(logger.isTraceEnabled()){

             logger.trace("Using ProxyCreatorSupport copy: " + copy);

          }

         //调用ProxyFactory生成AOPProxy代理

          return getProxy(copy.createAopProxy());

     }

   //使用createAopProxy方法返回的AOPProxy对象产生AOPProxy代理对象

protected Object getProxy(AopProxy aopProxy){

      return aopProxy.getProxy(this.proxyClassLoader);

 }

.......

}

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

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

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

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

AOPProxyFactory的getSingletonInstance和newPrototypeInstance方法均通过调用AOPCreatorSupport的createAopProxy()方法获取AOPProxy,主要源码如下:

public class ProxyCreatorSupport extends AdvisedSupport {

  //AOPProxy工厂

  private AopProxyFactory aopProxyFactory;

  //当第一个AOPProxy代理对象被创建时,设置为true

   private boolean active = false;

   public AopProxyFactory getAopProxyFactory(){

          return this.aopProxyFactory;

   }

  //默认使用DefaultAopProxyFactory作用AOP代理工厂

public ProxyCreatorSuppport(){

           this.aopProxyFactory = new DefaultAopProxyFactory();

 }

//创建AOPProxy代理的入口方法

protected final synchronized AopProxy createAopProxy(){

        if(!this.active){

               activate();

         }

       //调用DefaultAopProxyFactory的创建AOPProxy代理的方法

        return getAopProxyFactory().createAopProxy(this);

  }

//激活AOP代理配置,向容器注册代理回调监听器,第一次创建AOP代理时调用

private void activate(){

          this.active = true;

          for(AdvisedSupportListener listener : this.listeners){

               listener.activated(this);

           }

  }

......

}

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

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

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

public class DefaultAopProxyFactory implements AopProxyFactory,Serializable {

      //判断CGLIB类库是否在classpath中

     private static final boolean cglibAvailable = ClassUtils.isPresent("net.sf.cglib.Enhancer",DefaultAopProxyFactory.class.getClassLoader());

     //创建AOP代理对象

     public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {

          //如果AOP使用显示优化,或者配置了目标类,或者只使用Spring支持的代理接口

           if(config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)){

              //获取AOP配置的目标类

               Class targetClass = config.getTargetClass();

               if(targetClass ==  null){

                   throw new AopConfigException("TargetSource cannot determine target class: " + "Either an interface or a target is required for proxy creation.");

               }

               //如果配置的AOP目标类是接口,则使用JDK动态代理机制来生成AOP代理

                if(targetClass.isInterface()){

                      return new JdkDynamicAopProxy(config);

                 }

               //如果AOP配置的目标类不是接口,则使用CGLIB的方式来生成AOP代理

                 if(!cglibAvailable){

                     throw new AopConfigException("Cannot proxy target class because CGLIB2 is not available." + "Add CGLIB to the class path or specify proxy interface.");

                }

                return CglibProxyFactory.createCglibProxy(config);

         }

         else{

                 return new JdkDynamicAopProxy(config);

            }

    }

  //判断AOP是否只配置了SpringProxy代理接口或者没有配置任何代理接口

     private boolean hasNoUserSuppliedProxyInterfaces(AdvisedSupport config){

           //获取AOP配置的所有AOP代理接口

             Class[] interfaces = config.getProxiedInterfaces();

              return (interfaces.length == 0 || (interfaces.length ==1 && SpringProxy.class.equals(interfaces[0])));

       }

}

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

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

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

final class JdkDynamicAopProxy implements AopProxy,InvocationHandler,Serializable {

   .....

  //JdkDynamicAopProxy的构造方法

     public JdkDynamicAopProxy(AdvisedSupport config) throws AopConfigException {

             Assert.notNull(config,"AdvisedSupport must not be null");

             //获取AOPBeanFactory中配置的通知器链和目标源

              if(config.getAdvisors().length == 0 && config.getTargetSource() == AdvisedSupport.EMPTY_TARGET_SOURCE) {

                     throw new AopConfigException("No advisors and no TargetSource specified");

               }

               //为当前对象设置AOP设置

                this.advised = config;

         }

         //获取AOP代理对象的入口方法

         public Object getProxy(){

               return getProxy(ClassUtils.getDefaultClassLoader());

         }

        //创建AOP代理对象

          public Object getProxy(ClassLoader classLoader){

               if(logger.isDebugEnabled()){

                    logger.debug("Creating JDK dynamic proxy: target source is " + this.advised.getTargetSource());

                }

               //获取AOPBeanFactory中配置的代理接口

                Class[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised);

                //查找代理目标的接口中是否定义equals()和hashCode()方法

                  findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);

               //使用JDK的动态代理机制创建AOP代理对象

                  return Proxy.newProxyInstance(classLoader,proxiedInterfaces,this);

           }

           //查找给定类或接口中是否定义了equals()和hashCode()方法

            private void findDefinedEqualsAndHashCodeMethods(Class[] proxiedInterfaces){

                //遍历给定的类、接口数组

                  for(Class proxiedInterface : proxiedInterfaces){

                       //获取给定类/接口中所有声明的方法

                        Method[] methods = proxiedInterface.getDeclaredMethods();

                        //遍历类/接口中的声明的方法

                        for(Method method : methods){

                             //如果方法是equals()方法,则设置当前对象equalsDefined属性

                               if(AopUtils.isEqualsMethod(method)){

                                    this.equalsDefined = true;

                                }

                  //如果方法是hashCode()方法,则设置当前对象hashCodeDefined属性

                    if(AopUtils.isHashCodeMethod(method)){

                             this.hashCodeDefined = true;

                     }

                    if(this.equalsDefined && this.hashCodeDefined){

                              return;

                      }

               }

           }

     }

   //AOP代理对象的回调方法

      public Object invoke(Object proxy,Method method,Object[] args) throws Throwable {

                MethodInvocation invocation;

                 Object oldProxy = null;

                 boolean setProxyContext = false;

                 //获取通知的目标源

                   TargetSource targetSource = this.advised.targetSource;

                    Class targetClass = null;

                     Object target = null;

                    try{

                           //如果代理目标对象的接口中没有定义equals()方法,且当前调用的方法是equals()方法,即目标对象没有自己实现equals()方法

                             if(!this.equalsDefined && AopUtils.isEqualsMethod(method)){

                                   return equals(args[0]);

                              }

                          //如果代理目标对象的接口中没有定义hashCode()方法,且当前调用的方法是hashCode()方法,即目标对象没有自己实现hashCode()方法

                           if(!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)){

                              return hashCode();

                           }

                          //如果AOP配置了通知,使用反射机制调用通知的同名方法

                          if(!this.advised.opaque && method.getDeclaringClass().isInterface() && method.getDeclaringClass().isAssignableFrom(Advised.class)){

                                    return AopUtils.invokeJoinpointUsingReflection(this.advised,method,args);

                           }

                           Object retval;

                           //如果当前通知暴露了代理,则将当前代理使用currentProxy()方法变为可用代理

                            if(this.advised.exposeProxy){

                                 oldProxy = AopContext.setCurrentProxy(proxy);

                                  setProxyContext = true;

                             }

                            //获取目标对象

                             target = targetSource.getTarget();

                             if(target != null){

                                 targetClass = target.getClass();

                              }

                             //获取目标对象方法配置的拦截器(通知器)链

                             List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method,targetClass);

                             //如果没有配置任何通知

                             if(chain.isEmpty()){

                               //没有配置通知,使用反射直接调用目标对象的方法,并获取方法返回值

                                 retVal = AopUtils.invokeJointUsingReflection(target,method,args);

                             }

                            //如果配置了通知

                           else{

                             //为目标对象创建方法回调对象,需要在调用通知之后才调用目标对象的方法

                              invocation = new ReflectiveMethodInvocation(proxy,target,method,args,targetClass,chain);

                             //调用通知链,沿着通知器链调用所有配置的通知

                              retVal = invocation.proceed();

                          }

                          //如果方法有返回值,则将代理对象作为方法返回

                          if(retVal != null && retVal == target && method.getReturnType().isInstance(proxy) &&

                                  !RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {

                                               retVal = proxy;

                           }

                           return proxy;

          }

          finally{

                if(target != null && !targetSource.isStatic()){

                    //释放目标对象

                     targetSource.releaseTarget(target);

                 }

                 if(setProxyContext){

                        //存储代理对象

                      AopContext.setCurrentProxy(oldProxy);

                  }

               }

          }

.......

}

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

5、CglibProxyFactory创建AOPProxy代理:

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

//通过CGLIB方式创建AOP代理对象

public Object getProxy(ClassLoader classLoader){

            if(logger.isDebugEnabled) {

                 logger.debug("Creating CGLIB2 proxy: target source is " + this.advised.getTargetSource());

             }

             try{

                 //从代理创建辅助类中获取在Ioc容器中配置的目标对象

                   Class rootClass = this.advised.getTargetClass();

                    Assert.state(rootClass != null,"Target class must be available for creating a CGLIB proxy");

                    //将目标对象本身作为自己的基类

                     Class proxySuperClass = rootClass;

                     //检查获取到的目标类是否是CGLIB产生的

                      if(AopUtils.isCglibProxyClass(rootClass)){

                         //如果目标类是有CGLIB产生的,获取目标类的基类

                           proxySuperClass = rootClass.getSuperClass();

                          //获取目标类的接口

                            Class[] additionalInterfaces = rootClass.getInterfaces();

                          //将目标类的接口添加到容器AOP代理创建辅助类的配置中

                            for(Class additionalInterface : additionalInterfaces){

                                  this.advised.addInterface(additionalInterface);

                             }

                           }

                          //检验代理基类

                           validateClassIfNecessary(proxySuperClass);

                          //配置CGLIB的Enhancer类,Enhancer是CGLIB的主要操作类

                            Enhancer enhancer = createEnhancer();

                            if(classLoader != null){

                                 enhancer.setClassLoader(classLoader);

                                  if(classLoader instanceof SmartClassLoader && ((SmartClassLoader)classLoader).isClassReloadable(proxySuperClass)){

                                           enhancer.setUseCache(false);

                                   }

                                }

                                //设置enhancer的基类

                                enhancer.setSuperclass(proxySuperClass);

                                enhancer.setStrategy(new UndeclaredThrowableStrategy(UndeclaredThrowableException.class));

                                //设置enhancer的接口

                                enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));

                                enhancer.setInterceptDuringConstruction(false);

                                //设置enhancer的回调方法

                                  Callback[] callbacks = getCallbacks(rootClass);

                                  enhancer.setCallbacks(callbacks);

                                  //将通知器中配置作为enhancer的方法过滤

                                   enhancer.setCallbackFilter(new ProxyCallbackFilter( 

                                                this.advised.getCofigurationOnlyCopy(),this.fixedInterceptorMap,this.fixedInterceptorOffset));       

                                    Class[] types = new Class[callbacks.length];

                                    for(int x=0;x<types.length;x++){

                                      types[x] = callbacks[x].getClass();

                                    }

                                   //设置enhancer的回调类型

                                    enhancer.setCallbackTypes(types);

                                   //创建代理对象

                                    Object proxy;

                                    if(this.constructorArgs != null){

                                          proxy = enhancer.create(this.constructorArgTypes,this.constructorArgs);

                                     }

                                     else{

                                            proxy = enhancer.create();

                                      }

                                     return proxy;

                            }

                           catch(CodeGenerationException ex){

                                throw new AopConfigException("Could not generate CGLIB subclass of class [" +

                                        this.advised.getTargetClass() + "]:" +

                                         "Common causes of this problem include using a final class or a non-visible class",ex);

                          }

                         catch(IllegalArgumentException ex){

                             throw new AopConfigException("Could not generate CGLIB subclass of class [" +

                                           this.advised.getTargetClass() + "]: " +

                                           "Common cause of this problem include using a final class or a non-visible class",ex);

                                }

                              catch(Exception ex){

                                    throw new AopConfigException("Unexpected AOP exception" ,ex);

                               }

                       }

              //获取给定类的回调通知

                private Callback[] getCallbacks(Class rootClass) throws Exception{

                    //优化参数

                      boolean exposeProxy = this.advised.isExposeProxy();

                      boolean isFrozen = this.advised.isFrozen();

                      boolean isStatic = this.advised.getTargetSource().isStatic();

                      //根据AOP配置创建一个动态通知拦截器,CGLIB创建的动态代理会自动调用

                      //DynamicAdvisedInterceptor类的intercept方法对目标对象进行拦截处理

                        Callback aopInterceptor = new DynamicAdvisedInterceptor(this.advised);

                        Callback targetInterceptor;

                        //根据是否暴露代理,创建直接应用目标的通知

                        if(exposeProxy){

                            targetInterceptor = isStatic ? new StaticUnadvisedExposedInterceptor(this.advised.getTargetSource().getTarget()) :

                                                                                 new DynamicUnadvisedExposedInterceptor(this.advised.getTargetSource());

                         }

                         else{

                              targetInterceptor = isStatic ? new StaticUnadvisedInterceptor(this.advised.getTargetSource().getTarget()):

                                                                                  new DynamicUnadvisedInterceptor(this.advised.getTargetSource());

                        }

                       //创建目标分发器

                        Callback targetDispatcher = isStatic ? new StaticDispatcher(this.advised.getTargetSource().getTarget()) : new SerializableNoOp();

                        Callback[] mainCallbacks = new Callback[]{

                           aopInterceptor,//普通通知

                           targetIntercepor,//如果优化则不考虑配置的通知

                           new SerializableNoOp(),//没有被覆盖的方法

                           targetDispatcher,this.advisedDispatcher,

                            new EqualsInterceptor(this.advised),

                            new HashCodeInterceptor(this.advised)

                         };

                         Callback[] callbacks;

                        //如果目标是静态的,并且通知链被冻结,则使用优化AOP调用,直接对方法使用固定的通知链

                         if(isStatic && isFrozen){

                             Method[] methods = rootClass.getMethods();

                             Callback[] fixedCallbacks = new Callback[method.length];

                             this.fixedInterceptorMap = new HashMap<String,Integer>(methods.length);

                             for(int x=0;x<methods;x++){

                                   List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(methods[x],rootClass);

                                   fixedCallbacks[x] = new FixedChainStaticTargetInterceptor(chain,this.advised.getTargetSource().getTarget(),this.advised.getTargetClass());

                                   this.fixedInterceptorMap.put(methods[x].toString(),x);

                           }

                           //将固定回调和主要回调拷贝到回调数组中

                             callbacks = new Callback[mainCallbacks.length + fixedCallbacks.length];

                              System.arraycopy(mainCallbacks,0,callbacks,0,mainCallbacks.length);

                               System.arraycopy(fixedCallbacks,0,callbacks,mainCallbacks.length,fixedCallbacks.length);

                               this.fixedInterceptorOffset = mainCallbacks.length;

                         }

                       //如果目标不是静态的,或者通知链不被冻结,则使用AOP主要的通知

                        else{

                             callbacks = mainCallbacks;

                         }

                           return callbacks;

         }

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

 //CGLIB回调AOP拦截器链

public Object intercept(Object proxy,Method method,Object[] args,MethodProxy methodProxy) throws Throwable{

           Object oldProxy = null;

           boolean setProxyContext = false;

           Class targetClass = null;

           Object target = null;

           try{

               //如果通知器暴露了代理

                if(this.advised.exposedProxy){

                  //设置给定的代理对象为要被拦截的代理

                   oldProxy = AopContext.setCurrentProxy(proxy);

                    setProxyContext = true;

                  }

                //获取目标对象

                  target = getTarget();

                  if(target != null){

                   targetClass = target.getClass();

                  }

                  //获取AOP配置的通知

                    List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method,targetClass);

                   Object retVal;

                   //如果没有配置通知

                   if(chain.isEmpty() && Modifier.isPublic(method.getModifiers())){

                       //直接调用目标对象的方法

                         retVal = methodProxy.invoke(target,args);

                     }

                     //如果配置了通知

                     else{

                       //通过CglibMethodInvocation来启动配置的通知

                         retVal = new CglibMethodInvocation(proxy,target,method,args,targetClass,chain,methodProxy).proceed();

                      }

                      //获取目标对象对象方法的回调结果,如果有必要则封装为代理

                       retVal = massageReturnTypeIfNecessary(proxy,target,method,retVal);

                       return retVal;

                }

                finally{

                       if(target != null){

                            releaseTarget(target);

                       }

                       if(setProxyContext){

                          //存储被回调的代理

                           AopContext.setCurrentProxy(oldProxy);

                        }

                     }

                }

6、目标对象方法的调用

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

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

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

//通过反射机制直接调用目标对象方法

public static Object invokeJoinpointUsingReflection(Object target,Method method,Object[] args) throws Throwable {

          try{

            //通过反射使给定的方法可以访问,主要是对protected和private方法使用,取消严格访问控制权限的限制

             ReflectionUtils.makeAccessible(method);

            //使用反射机制调用目标对象的方法

              return method.invoke(target,args);

          }

          catch(InvocationTargetException ex){

               throw ex.getTargetException();

           }

          catch(IllegalArgumentException ex){

               throw new AopInvocationException("AOP configuration seems to be invalid: tried calling method [" +

                          method + "] on target [" + target + "]",ex);

            }

            catch(IllegalAccessException ex){

                    throw new AopInvocationException("Could not access method [" + method + "]",ex);

            }

    }

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

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

retVal = methodProxy.inoke(target,args);

methodProxy是CGLIB中MethodProxy类的对象。

7、AOP拦截器链的调用:

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

//通用通知器链

public Object proceed() throws Throwable {

          //如果拦截器链中通知已经调用完毕

           if(this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size()-1){

              //这个方法调用AopUtils.inokeJoinpointUsingReflection方法,通过反射机制直接调用目标对象方法

                return invokeJoinpoint();

           }

           //获取拦截器链中的通知器或通知

          Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMathcers.get(++this.currentInterceptorIndex);

          //如果获取的通知器或通知是动态匹配方法拦截器类型

           if(interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher){

              //动态匹配方法拦截器

                InterceptorAndDynamicMethodMathcer dm = (InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;

             if(dm.methodMatcher.matches(this.method,this.targetClass,this.arguments)){

                  //如果匹配,调用拦截器的方法

                  return dm.interceptor.invoke(this);

              }

             else{

                //如果不匹配,递归调用proceed()方法,知道拦截器链被全部调用为止

                 return proceed();

            }

          }

          else{

             //如果不是动态匹配方法拦截器,则切入点在构造对象之前进行静态匹配,调用拦截器的方法

                return ((MethodInterceptor)interceptorOrInterceptionAdvice).invoke(this);

             }

    }

                

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值