源碼通透-spring-AOP-5-AspectJAwareAdvisorAutoProxyCreator

源碼通透-spring-AOP-5-AspectJAwareAdvisorAutoProxyCreator


spring源碼版本:spring5.0

jdk: 1.8

我保存的源碼地址:https://gitee.com/paincupid/spring-framework.git

或者官網地址:https://github.com/spring-projects/spring-framework.git

更多源碼文章:https://github.com/arthur-dy-lee/arthur-dy-lee-note

作用

主要爲AspectJ切面服務。具體的針對如何創建代理,是在父類中(AbstractAutoProxyCreator#createProxy)實現。

AbstractAutoProxyCreator 實現了BeanPostProcess接口,所以在創建時,調用``postProcessAfterInitialization`方法

1、獲取可用的切面advice,從beanFactory中查找可用的切面

2、由ProxyFactory來創建代理對象。默認是採用JDK靜態代理,對beanClass爲非接口實現類採取CGLIB動態代理

一、AspectJAwareAdvisorAutoProxyCreator類繼承關係


AspectJAwareAdvisorAutoProxyCreator

SmartInstantiationAwareBeanPostProcessor是beanPostProcessor接口的子類,spring在實例化bean對象的時候會調用beanPostProcessor的公有接口。

BeanPostProcessor,針對所有Spring上下文中所有的bean,可以在配置文檔applicationContext.xml中配置一個BeanPostProcessor,然後對所有的bean進行一個初始化之前和之後的代理。

BeanPostProcessor接口中有兩個方法: postProcessBeforeInitialization和postProcessAfterInitialization。 postProcessBeforeInitialization方法在bean初始化之前執行, postProcessAfterInitialization方法在bean初始化之後執行。

afterPropertiesSet 和init-method之間的執行順序是afterPropertiesSet 先執行,init-method 後執行。從BeanPostProcessor的作用,可以看出最先執行的是postProcessBeforeInitialization,然後是afterPropertiesSet,然後是init-method,然後是postProcessAfterInitialization。

postProcessAfterInitialization是bean對象被實例化的最後一步操作的

bean實例化順序,看下面代碼:

AbstractAutowireCapableBeanFactory#initializeBean

1、applyBeanPostProcessorsBeforeInitialization–>beanProcessor.postProcessBeforeInitialization

2、invokeInitMethods(beanName, wrappedBean, mbd); -->

((InitializingBean) bean).afterPropertiesSet(); 

invokeCustomInitMethod(beanName, bean, mbd);

3、applyBeanPostProcessorsAfterInitialization --> beanProcessor.postProcessAfterInitialization(result, beanName);

/**
 * Initialize the given bean instance, applying factory callbacks
 * as well as init methods and bean post processors.
 * <p>Called from {@link #createBean} for traditionally defined beans,
 * and from {@link #initializeBean} for existing bean instances.
 */
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
    if (System.getSecurityManager() != null) {
        AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
            invokeAwareMethods(beanName, bean);
            return null;
        }, getAccessControlContext());
    }
    else {
        invokeAwareMethods(beanName, bean);
    }

    Object wrappedBean = bean;
    if (mbd == null || !mbd.isSynthetic()) {
        wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
    }

    try {
        invokeInitMethods(beanName, wrappedBean, mbd);
    }
    catch (Throwable ex) {
        throw new BeanCreationException((mbd != null ? mbd.getResourceDescription() : null),beanName, "Invocation of init method failed", ex);
    }
    if (mbd == null || !mbd.isSynthetic()) {
        wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
    }

    return wrappedBean;
}

二、AbstractAutoProxyCreator#postProcessAfterInitialization()-創建代理的入口函數


postProcessAfterInitialization方法主要調用順序

AbstractAutoProxyCreator#postProcessAfterInitialization 入口類

-wrapIfNecessary 得到可用的切面,並緩存起來

– AbstractAdvisorAutoProxyCreator#getAdvicesAndAdvisorsForBean

— findEligibleAdvisors

----1.findCandidateAdvisors查找所有的切面

----- AbstractAdvisorAutoProxyCreator#findCandidateAdvisors

------ BeanFactoryAdvisorRetrievalHelper#findAdvisorBeans 查找接口類型爲Advisor的

advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Advisor.class, true, false);

advisors.add(this.beanFactory.getBean(name, Advisor.class));

advisors.add(this.beanFactory.getBean(name, Advisor.class));

----2.findAdvisorsThatCanApply在所有的切面有,查找可用切面

----- AopUtils#findAdvisorsThatCanApply

------ AopUtils#canApply

------- BeanFactoryTransactionAttributeSourceAdvisor#getPointcut 如果是事務類的會進入到BeanFactoryTransactionAttributeSourceAdvisor

AbstractAutoProxyCreator#postProcessAfterInitialization()

/**
 * Create a proxy with the configured interceptors if the bean is
 * identified as one to proxy by the subclass.
 * @see #getAdvicesAndAdvisorsForBean
 */
@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
    if (bean != null) {
        // 1、如果之前調用過getEarlyBeanReference獲取包裝目標對象到AOP代理對象(如果需要),則不再執行 
        Object cacheKey = getCacheKey(bean.getClass(), beanName);
        if (!this.earlyProxyReferences.contains(cacheKey)) {
            //2、包裝目標對象到AOP代理對象(如果需要)
            return wrapIfNecessary(bean, beanName, cacheKey);
        }
    }
    return bean;
}

getEarlyBeanReferencepostProcessAfterInitialization是二者選一的,而且單例Bean目標對象只能被增強一次

三、 AbstractAutoProxyCreator#wrapIfNecessary() 如果bean需要被代理,包裝bean返回代理對象


wrapIfNecessary 裏面就2個重要方法:
1、getAdvicesAndAdvisorsForBean
2、createProxy

/**
 * Wrap the given bean if necessary, i.e. if it is eligible for being proxied.
 * @param bean the raw bean instance //被代理的bean實例
 * @param beanName the name of the bean //bean名稱
 * @param cacheKey the cache key for metadata access
 * @return a proxy wrapping the bean, or the raw bean instance as-is
 */
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
    //通過TargetSourceCreator進行自定義TargetSource不需要包裝  
    if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
        return bean;
    }
    //不應該被增強對象不需要包裝 
    if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
        return bean;
    }
    //Advice/Advisor/AopInfrastructureBean接口的beanClass不進行代理以及對beanName爲aop內的切面名也不進行代理,此處可查看子類複寫的sholdSkip()方法
    if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
        this.advisedBeans.put(cacheKey, Boolean.FALSE);
        return bean;
    }

    // Create proxy if we have advice. 
    //獲取可用的切面advice,並創建代理
    Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
    if (specificInterceptors != DO_NOT_PROXY) {
        // 將cacheKey添加到已經被增強列表,防止多次增強
        this.advisedBeans.put(cacheKey, Boolean.TRUE);
        // 創建代理對象 <-------------
        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;
}

從類繼承結構上看,AbstractAdvisorAutoProxyCreator和BeanNameAutoProxyCreator都繼承了:AbstractAutoProxyCreator。AbstractAdvisorAutoProxyCreator和BeanNameAutoProxyCreator都有getAdvicesAndAdvisorsForBean方法,下面且看AbstractAdvisorAutoProxyCreator

AbstractAutoProxyCreator有兩個子類

  • 一個是BeanNameAutoProxyCreator,它是基於bean名字的自動代理類。 它會給spring容器中bean名字與指定名字匹配的bean自動創建代理。其中匹配的規則定義在PatternMatchUtils.simpleMatch()方法中。注意:若需要給某個FactoryBean創建代理,可以在bean名字前面加上&.

  • 第二類是AbstractAdvisorAutoProxyCreator,相對BeanNameAutoProxyCreator而言,它更爲強大,它會自動獲取spring容器中註冊的所有的Advisor類(除了子類中isEligibleAdvisorBean()方法指定的不滿足條件的Advisor除外。),然後自動給spring容器中滿足Advisor中pointCut創建代理。

    DefaultAdvisorAutoProxyCreator是默認實現,默認會自動代理所有的Advisor,當然也可以通過設置usePrefix和advisorBeanNamePrefix來過濾部分advisor

    AspectJAwareAdvisorAutoProxyCreator用於支持AspectJ方式的自動代理。

四、 AbstractAdvisorAutoProxyCreator.getAdvicesAndAdvisorsForBean 獲取可用的切面advices和Advisors


@Override
@Nullable
protected Object[] getAdvicesAndAdvisorsForBean(
    Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {

    List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
    if (advisors.isEmpty()) {
        return DO_NOT_PROXY;
    }
    return advisors.toArray();
}
/**
 * Find all eligible Advisors for auto-proxying this class.
 * @param beanClass the clazz to find advisors for
 * @param beanName the name of the currently proxied bean
 * @return the empty List, not {@code null},
 * if there are no pointcuts or interceptors
 * @see #findCandidateAdvisors
 * @see #sortAdvisors
 * @see #extendAdvisors
 */
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
    //Find all candidate Advisors to use in auto-proxying.
    //在自動代理中,查找所有advisors
    List<Advisor> candidateAdvisors = findCandidateAdvisors();
    //Search the given candidate Advisors to find all Advisors that can apply to the specified bean.
    //在所有的advisors中查找符合條件的advisors
    List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
    extendAdvisors(eligibleAdvisors);
    if (!eligibleAdvisors.isEmpty()) {
        eligibleAdvisors = sortAdvisors(eligibleAdvisors);
    }
    return eligibleAdvisors;
}

findCandidateAdvisors()方法有2個實現方法:

  • AbstractAdvisorAutoProxyCreator.findCandidateAdvisors()
  • AnnotationAwareAspectJAutoProxyCreator.findCandidateAdvisors()

AnnotationAwareAspectJAutoProxyCreator extends AspectJAwareAdvisorAutoProxyCreator

AnnotationAwareAspectJAutoProxyCreator重寫了findCandidateAdvisors()

AnnotationAwareAspectJAutoProxyCreator註解AOP解析,可以看這篇文章:https://blog.csdn.net/heroqiang/article/details/79037741

下面看AbstractAdvisorAutoProxyCreator.findCandidateAdvisors()

findCandidateAdvisors會在beanFactory中查找所有的Advisor,調用BeanFactoryAdvisorRetrievalHelper.findAdvisorBeans

BeanFactoryUtils.beanNamesForTypeIncludingAncestors()方法,查找實現接口Advisor的實現類,其中BeanFactoryTransactionAttributeSourceAdvisor、TransactionInterceptor都是Advisor的實現類,在事務AOP時用到。

/**
 * Find all eligible Advisor beans in the current bean factory,
 * ignoring FactoryBeans and excluding beans that are currently in creation.
 * @return the list of {@link org.springframework.aop.Advisor} beans
 * @see #isEligibleBean
 */
public List<Advisor> findAdvisorBeans() {
    // Determine list of advisor bean names, if not cached already.
    String[] advisorNames = null;
    synchronized (this) {
        advisorNames = this.cachedAdvisorBeanNames;
        if (advisorNames == null) {
            // Do not initialize FactoryBeans here: We need to leave all regular beans
            // uninitialized to let the auto-proxy creator apply to them!
            //查找實現接口Advisor的類,其中BeanFactoryTransactionAttributeSourceAdvisor、TransactionInterceptor都是Advisor的實現類,在事務AOP時用到。
            advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
                this.beanFactory, Advisor.class, true, false);
            this.cachedAdvisorBeanNames = advisorNames;
        }
    }
    List<Advisor> advisors = new LinkedList<>();
    for (String name : advisorNames) {
        if (isEligibleBean(name)) {
           //....            
           advisors.add(this.beanFactory.getBean(name, Advisor.class)); 
        }
    }
    return advisors;
}

五、AbstractAutoProxyCreator#createProxy 創建AOP代理


/**
 * Create an AOP proxy for the given bean.
 * @param beanClass the class of the bean
 * @param beanName the name of the bean
 * @param specificInterceptors the set of interceptors that is
 * specific to this bean (may be empty, but not null)
 * @param targetSource the TargetSource for the proxy,
 * already pre-configured to access the bean
 * @return the AOP proxy for the bean
 * @see #buildAdvisors
 */
protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
                             @Nullable Object[] specificInterceptors, TargetSource targetSource) {

    if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
        AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
    }
	//採用ProxyFactory對象來創建代理對象
    ProxyFactory proxyFactory = new ProxyFactory();
    proxyFactory.copyFrom(this);
	//是否採用動態代理
    if (!proxyFactory.isProxyTargetClass()) {
        if (shouldProxyTargetClass(beanClass, beanName)) {
            proxyFactory.setProxyTargetClass(true);
        }
        else {
            //Check the interfaces on the given bean class and apply them to the ProxyFactory, if appropriate.
            // 查看beanClass對應的類是否含有InitializingBean.class/DisposableBean.class/Aware.class接口,以及groovy.lang.GroovyObject,.cglib.proxy.Factory,.bytebuddy.MockAccess。無則採用靜態代理,有則採用動態代理
            evaluateProxyInterfaces(beanClass, proxyFactory);
        }
    }
	//應用中如果存在高優先級的切面,先它們放到前面去。決定切面的順序
    Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
    proxyFactory.addAdvisors(advisors);
    proxyFactory.setTargetSource(targetSource);
    customizeProxyFactory(proxyFactory);

    proxyFactory.setFrozen(this.freezeProxy);
    if (advisorsPreFiltered()) {
        proxyFactory.setPreFiltered(true);
    }

    return proxyFactory.getProxy(getProxyClassLoader());
}

5.1 創建 DefaultAopProxyFactory

當創建ProxyFactory時,因爲它繼承了ProxyCreatorSupport,所以會先調用父親的構造函數,這時會創建DefaultAopProxyFactory

ProxyFactory proxyFactory = new ProxyFactory();

public class ProxyFactory extends ProxyCreatorSupport

public ProxyCreatorSupport() { this.aopProxyFactory = new DefaultAopProxyFactory();}

proxyFactory#getProxy() 根據proxyFactory中的設置參數,創建代理對象
這裏的proxyFactory就是DefaultAopProxyFactory

/**
 * Create a new proxy according to the settings in this factory.
 * <p>Can be called repeatedly. Effect will vary if we've added
 * or removed interfaces. Can add and remove interceptors.
 * <p>Uses the given class loader (if necessary for proxy creation).
 * @param classLoader the class loader to create the proxy with
 * (or {@code null} for the low-level proxy facility's default)
 * @return the proxy object
 */
public Object getProxy(@Nullable ClassLoader classLoader) {
    return createAopProxy().getProxy(classLoader); // <---------
}

下面幾章重點分析

createAopProxy().getProxy(classLoader)

六、 createAopProxy:JDK代理或CGLIB代理


6.1 ProxyCreatorSupport#createAopProxy 創建AOP代理:使用JDK或CGLIB

ProxyCreatorSupport#createAopProxy 時,getAopProxyFactory() 是指 DefaultAopProxyFactory,所以getAopProxyFactory().createAopProxy是會調用DefaultAopProxyFactory#createAopProxy

/**
 * Subclasses should call this to get a new AOP proxy. They should <b>not</b>
 * create an AOP proxy with {@code this} as an argument.
 */
protected final synchronized AopProxy createAopProxy() {
    if (!this.active) {
        activate();
    }
    return getAopProxyFactory().createAopProxy(this);
}

/**
 * Return the AopProxyFactory that this ProxyConfig uses.
 */
public AopProxyFactory getAopProxyFactory() {
    return this.aopProxyFactory;
}

6.2 DefaultAopProxyFactory#createAopProxy 決定使用cglib還是jdk代理

默認是採用JDK代理,對beanClass爲非接口實現類採取CGLIB動態代理。

碰到以下三種情況使用CGLIB

  1. ProxyConfig的isOptimize方法爲true,這表示讓Spring自己去優化。可以通過 ProxyFactory 的 setOptimize(true) 方法讓 ProxyFactory 啓動優化代理方式,這樣,針對接口的代理也會使用 CglibAopProxy
  2. ProxyConfig的isProxyTargetClass方法爲true,這表示配置了proxy-target-class=”true”
  3. ProxyConfig滿足hasNoUserSuppliedProxyInterfaces方法執行結果爲true,這表示<bean>對象沒有實現任何接口或者實現的接口是SpringProxy接口
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
    if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
        Class<?> targetClass = config.getTargetClass();
        //...
        if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
            return new JdkDynamicAopProxy(config);
        }
        return new ObjenesisCglibAopProxy(config);
    }
    else {
        return new JdkDynamicAopProxy(config);
    }
}

在創建AOP代理後

return createAopProxy().getProxy(classLoader);

再來看下一章的 getProxy方法。

七、 getProxy 選擇對應的getProxy方法創建代理對象


最後根據jdk還是cglib(ObjenesisCglibAopProxy),選擇對應的getProxy方法創建代理對象。

下面分別看JdkDynamicAopProxy#getProxy 和 CglibAopProxy#getProxy

7.1 JdkDynamicAopProxy#getProxy

@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
    //.....
    //拿到所有要代理的接口
    Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
    //尋找這些接口方法裏面有沒有equals方法和hashCode方法,同時都有的話打個標記,尋找結束,equals方法和hashCode方法有特殊處理
    findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
    return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}

JDK的代理執行,是在 JdkDynamicAopProxy.invoke() 中執行的,後面執行調用的時候 ,再來分析這個方法。

Proxy#newProxyInstance

@CallerSensitive
public static Object newProxyInstance(ClassLoader loader,
                                      Class<?>[] interfaces,
                                      InvocationHandler h)
    throws IllegalArgumentException
{
    Objects.requireNonNull(h);

    final Class<?>[] intfs = interfaces.clone();
    final SecurityManager sm = System.getSecurityManager();
    if (sm != null) {
        checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
    }

    /*
     * Look up or generate the designated proxy class.
     */
    Class<?> cl = getProxyClass0(loader, intfs);

    /*
     * Invoke its constructor with the designated invocation handler.
     */
    try {
        if (sm != null) {
            checkNewProxyPermission(Reflection.getCallerClass(), cl);
        }

        final Constructor<?> cons = cl.getConstructor(constructorParams);
        final InvocationHandler ih = h;
        if (!Modifier.isPublic(cl.getModifiers())) {
            AccessController.doPrivileged(new PrivilegedAction<Void>() {
                public Void run() {
                    cons.setAccessible(true);
                    return null;
                }
            });
        }
        return cons.newInstance(new Object[]{h});
    } catch (IllegalAccessException|InstantiationException e) {
        throw new InternalError(e.toString(), e);
    } catch (InvocationTargetException e) {
        Throwable t = e.getCause();
        if (t instanceof RuntimeException) {
            throw (RuntimeException) t;
        } else {
            throw new InternalError(t.toString(), t);
        }
    } catch (NoSuchMethodException e) {
        throw new InternalError(e.toString(), e);
    }
}

7.2 CglibAopProxy#getProxy 通過返射構造函數創建代理實例

作用:創建並配置 Enhancer, Enhancer 是CGLIB 主要的操作類,並將DynamicAdvisedInterceptor攔截器放到callback

因爲

class ObjenesisCglibAopProxy extends CglibAopProxy

但ObjenesisCglibAopProxy 並沒有覆蓋getProxy()方法,所以會調用父親的 CglibAopProxy#getProxy

@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
 	//....
    Class<?> rootClass = this.advised.getTargetClass();
    Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");

    Class<?> proxySuperClass = rootClass;
    if (ClassUtils.isCglibProxyClass(rootClass)) {
        proxySuperClass = rootClass.getSuperclass();
        Class<?>[] additionalInterfaces = rootClass.getInterfaces();
        for (Class<?> additionalInterface : additionalInterfaces) {
            this.advised.addInterface(additionalInterface);
        }
    }

    // Validate the class, writing log messages as necessary.
    validateClassIfNecessary(proxySuperClass, classLoader);

    // Configure CGLIB Enhancer...
    //創建並配置 Enhancer,  Enhancer 是CGLIB 主要的操作類
    Enhancer enhancer = createEnhancer();
    if (classLoader != null) {
        enhancer.setClassLoader(classLoader);
        if (classLoader instanceof SmartClassLoader &&
            ((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
            enhancer.setUseCache(false);
        }
    }
    //配置超類,代理類實現的接口,回調方法等
    enhancer.setSuperclass(proxySuperClass);
    enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
    enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
    enhancer.setStrategy(new ClassLoaderAwareUndeclaredThrowableStrategy(classLoader));

    Callback[] callbacks = getCallbacks(rootClass); // <--------------- 6.4.1
    Class<?>[] types = new Class<?>[callbacks.length];
    for (int x = 0; x < types.length; x++) {
        types[x] = callbacks[x].getClass();
    }
    // fixedInterceptorMap only populated at this point, after getCallbacks call above
    enhancer.setCallbackFilter(new ProxyCallbackFilter(
        this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
    enhancer.setCallbackTypes(types);

    // Generate the proxy class and create a proxy instance.
    return createProxyClassAndInstance(enhancer, callbacks); // <------ 6.4.2
}

7.2.1 CglibAopProxy#getCallbacks 來實現AOP代理的攔截

下面的代碼,我們可以看到創建了一個DynamicAdvisedInterceptor,它最後,被放到Callbacks裏面。當被代理的方法執行時,會執行DynamicAdvisedInterceptor.intercept()方法。後面執行調用的時候 ,再來分析這個方法。

在Callback[]中有的攔截器包括:

DynamicAdvisedInterceptor、AdvisedDispatcher、SerializableNoOp、EqualsInterceptor、HashCodeInterceptor。

以及根據exposeProxy屬性,以及是否是靜態對象來決定使用下面哪個攔截器

StaticUnadvisedExposedInterceptor、DynamicUnadvisedExposedInterceptor

StaticUnadvisedInterceptor、DynamicUnadvisedInterceptor

最後將上面這些攔截器放入到callback[]中,返回。

private Callback[] getCallbacks(Class<?> rootClass) throws Exception {
   // Parameters used for optimization choices...
   boolean exposeProxy = this.advised.isExposeProxy();
   boolean isFrozen = this.advised.isFrozen();
   boolean isStatic = this.advised.getTargetSource().isStatic();

   // Choose an "aop" interceptor (used for AOP calls).
   Callback aopInterceptor = new DynamicAdvisedInterceptor(this.advised); //<-----------

   // Choose a "straight to target" interceptor. (used for calls that are
   // unadvised but can return this). May be required to expose the proxy.
   Callback targetInterceptor;
   if (exposeProxy) {
      // 判斷被代理的對象是否是靜態的,如果是靜態的,則將目標對象緩存起來,每次都使用該對象即可,
      // 如果目標對象是動態的,則在DynamicUnadvisedExposedInterceptor中每次都生成一個新的
      // 目標對象,以織入後面的代理邏輯 
      targetInterceptor = (isStatic ?
            new StaticUnadvisedExposedInterceptor(this.advised.getTargetSource().getTarget()) :
            new DynamicUnadvisedExposedInterceptor(this.advised.getTargetSource()));
   }
   else {
      // 下面兩個類與上面兩個的唯一區別就在於是否使用AopContext暴露生成的代理對象 
      targetInterceptor = (isStatic ?
            new StaticUnadvisedInterceptor(this.advised.getTargetSource().getTarget()) :
            new DynamicUnadvisedInterceptor(this.advised.getTargetSource()));
   }

   // Choose a "direct to target" dispatcher (used for
   // unadvised calls to static targets that cannot return this).
   Callback targetDispatcher = (isStatic ?
         new StaticDispatcher(this.advised.getTargetSource().getTarget()) : new SerializableNoOp());

   Callback[] mainCallbacks = new Callback[] {
         aopInterceptor,  // for normal advice <-----DynamicAdvisedInterceptor放入callbacks中
         targetInterceptor,  // invoke target without considering advice, if optimized
         new SerializableNoOp(),  // no override for methods mapped to this
         targetDispatcher, this.advisedDispatcher,
         new EqualsInterceptor(this.advised),
         new HashCodeInterceptor(this.advised)
   };

   Callback[] callbacks;

   // If the target is a static one and the advice chain is frozen,
   // then we can make some optimizations by sending the AOP calls
   // direct to the target using the fixed chain for that method.
   if (isStatic && isFrozen) {
      Method[] methods = rootClass.getMethods();
      Callback[] fixedCallbacks = new Callback[methods.length];
      this.fixedInterceptorMap = new HashMap<>(methods.length);

      // TODO: small memory optimization here (can skip creation for methods with no advice)
      for (int x = 0; x < methods.length; 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);
      }
    
      // Now copy both the callbacks from mainCallbacks
      // and fixedCallbacks into the callbacks array.
      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;
   }
   else {
      callbacks = mainCallbacks;
   }
   return callbacks;
}

7.2.2 createProxyClassAndInstance 創建代理類和代理實例

如果上面createAOP時,創建的是ObjenesisCglibAopProxy,那麼createProxyClassAndInstance()會調用ObjenesisCglibAopProxy.createProxyClassAndInstance方法。

重點,還是將callbacks放到proxyInstance中。

@Override
@SuppressWarnings("unchecked")
protected Object createProxyClassAndInstance(Enhancer enhancer, Callback[] callbacks) {
   Class<?> proxyClass = enhancer.createClass();
   Object proxyInstance = null;

   if (objenesis.isWorthTrying()) {
      try {
         proxyInstance = objenesis.newInstance(proxyClass, enhancer.getUseCache());
      }//.....
   }

   if (proxyInstance == null) {
      // Regular instantiation via default constructor...
      try {
         Constructor<?> ctor = (this.constructorArgs != null ?
               proxyClass.getDeclaredConstructor(this.constructorArgTypes) :
               proxyClass.getDeclaredConstructor());
         ReflectionUtils.makeAccessible(ctor);
         proxyInstance = (this.constructorArgs != null ?
               ctor.newInstance(this.constructorArgs) : ctor.newInstance());
      }//....
   }

   ((Factory) proxyInstance).setCallbacks(callbacks);
   return proxyInstance;
}

7.3 StaticUnadvisedExposedInterceptor和DynamicUnadvisedExposedInterceptor區別

StaticUnadvisedExposedInterceptor#intercept

每次從線程副本中取舊的代理,然後執行

@Override
@Nullable
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
   Object oldProxy = null;
   try {
      oldProxy = AopContext.setCurrentProxy(proxy);
      Object retVal = methodProxy.invoke(this.target, args);
      return processReturnType(proxy, this.target, method, retVal);
   }
   finally {
      AopContext.setCurrentProxy(oldProxy);
   }
}

DynamicUnadvisedExposedInterceptor#intercept

每次取出要代理的目前對象,然後執行。

public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
   Object target = this.targetSource.getTarget();
   try {
      Object retVal = methodProxy.invoke(target, args);
      return processReturnType(proxy, target, method, retVal);
   }
   finally {
      if (target != null) {
         this.targetSource.releaseTarget(target);
      }
   }
}

參考:

Spring AOP源碼分析

更新源碼文章:https://github.com/arthur-dy-lee/arthur-dy-lee-note

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章