1. 程式人生 > 其它 >Spring原始碼分析(十)AOP原始碼分析

Spring原始碼分析(十)AOP原始碼分析

AOP中的幾個概念

Advisor 和 Advice

Advice

我們通常都會把他翻譯為通知,其實很不好理解,其實他還有另外一個意思,就是“建議”,我覺得把Advice理解為“建議”會更好。就是代理的邏輯。

比如,我們已經完成了一個功能,這時客戶跟我們說,我建議在這個功能之前可以再增加一些邏輯,再之後再增加一些邏輯。

在Spring中,Advice分為:

  1. 前置Advice:MethodBeforeAdvice
  2. 後置Advice:AfterReturningAdvice
  3. 環繞Advice:MethodInterceptor
  4. 異常Advice:ThrowsAdvice

在利用Spring AOP去生成一個代理物件時,我們可以設定這個代理物件的Advice。

而對於Advice來說,它只表示了“建議”,它沒有表示這個“建議”可以用在哪些方面。

就好比,我們已經完成了一個功能,客戶給這個功能提了一個建議,但是這個建議也許也能用到其他功能上。

這時,就出現了Advisor,表示一個Advice可以應用在哪些地方,而“哪些地方”就是Pointcut(切點)。

Pointcut

切點,表示我想讓哪些地方加上我的代理邏輯。

比如某個方法,

比如某些方法,

比如某些方法名字首為“find”的方法,

比如某個類下的所有方法,等等。

在Pointcut中,有一個MethodMatcher,表示方法匹配器。

Advisor

就等於Pointcut+Advice.

Spring中的AOP代理類是通過一個ProxyFactory類來實現的。

先簡單介紹下這個類的簡單用法:

public static void main(String[] args) {

AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);

UserInterface userService = (UserInterface) applicationContext.getBean("userService");

userService.test();

// testAop();

}

public static void testAop(){
ProxyFactory proxyFactory = new ProxyFactory();
// 設定目標物件
proxyFactory.setTarget(new UserService());
// proxyFactory.setTargetClass(UserService.class);

proxyFactory.addInterface(UserInterface.class); // 表示想使用jdk動態代理
proxyFactory.getTargetSource();
// 生成代理邏輯 ,注意這裡新增的只是一個Advice,底層是要封裝成一個Advisor來交給代理工廠管理的。
// 這裡添加了Advice,底層使用 DefaultPointcutAdvisor 封裝,它的PointCut是Pointcut.TRUE 表示匹配所有類的切點的都使用
proxyFactory.addAdvice(new MethodBeforeAdvice() {
@Override
public void before(Method method, Object[] args, Object target) throws Throwable {
System.out.println(method.getName()+"方法呼叫之前執行的代理邏輯");
}
});
// UserService 實現了 UserInterface 介面

// 生成代理物件 UserService 是個實現類,如果是cglib動態代理,代理類是可以強轉成它的,但是如果是jdk動態代理,它就不能強轉成UserService類
// 因為cglib是基於子類來實現的,jdk動態代理是基於介面實現類來的

// UserService proxy = (UserService) proxyFactory.getProxy();

// jdk動態代理 {代理類 extends Proxy implement 目標介面}
UserInterface proxy = (UserInterface) proxyFactory.getProxy();

proxy.test();
}

1:上面ProxyFactory的構造方法,會把傳進去的目標物件封裝成一個TargetSource

public void setTarget(Object target) {
        setTargetSource(new SingletonTargetSource(target));
    }

2: 還有一種設定目標物件的方式,就是:proxyFactory.setTargetClass(UserService.class);

    public void setTargetClass(@Nullable Class<?> targetClass) {
        this.targetSource = EmptyTargetSource.forClass(targetClass);
    }

兩種設定方式得到的this.targetSource 這個屬性是不一樣的,

一個是:EmptyTargetSource ,一個是SingletonTargetSource,他們都繼承了TargetSource,但是對於SingletonTargetSource來說,它的target屬性,和getTargetClass都是可以得到值的。

但是對於EmptyTargetSource 來說,它只有getTargetClass能得到值,因為是直接賦值的,它的getTarget是直接返回null的。

上面代理工廠ProxyFactory#getProxy得到一個代理類中,會先得到一個具體的代理工廠,有兩種jdk的代理工廠和cglib的代理工廠。

public Object getProxy() {
        return createAopProxy().getProxy();
    }

    protected final synchronized AopProxy createAopProxy() {
        if (!this.active) {
            activate();
        }
        // 預設用的就是DefaultAopProxyFactory
        return getAopProxyFactory().createAopProxy(this);
    }

DefaultAopProxyFactory#createAopProxy 中:

public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
        // Spring到底何時使用cglib,何時使用jdk動態代理
        // 如果設定的targetClass是一個介面,會使用jdk動態代理
        // 預設情況下(optimize為false, isProxyTargetClass為false), ProxyFactory添加了介面時,也會使用jdk動態代理

        // 這個config 就是外面的按個ProxyFactory 它的父類 extends ProxyConfig implements Advised
//        config.isOptimize() 跟CGlib優化 可以在外面設定 ,預設為false
//        config.isProxyTargetClass()  預設為false ,是否使用cglib,  這個屬性也可以通過 @EnableAspectJAutoProxy 註解設定,註解屬性裡面也有這個屬性
//     hasNoUserSuppliedProxyInterfaces 是不是沒有使用者提供的代理介面 :這個指的是 可以通過proxyFactory.addInterface() 新增介面
//        新增之後 hasNoUserSuppliedProxyInterfaces(config)會判斷   是否進入下面的邏輯
        if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
//            這個 getTargetClass() 就是外面setTarget或者 setTargetClass 之後可以得到的值
            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.");
            }
//            如果 targetClass 是介面就使用jdk的動態代理 ,如果外面是通過setTarget賦值的,那麼targetClass肯定不是介面,因為引數是個物件
//            setTargetClass  設定的可以是個介面
            if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
//                返回jdk的代理工廠
                return new JdkDynamicAopProxy(config);
            }
//            返回cglib的代理工廠
            return new ObjenesisCglibAopProxy(config);
        }
        else {
            return new JdkDynamicAopProxy(config);
        }
    }

而一般在我們使用過程中,如果只開啟了註解:@EnableAspectJAutoProxy ,Spring會根據類是否有介面來判斷是否用jdk動態代理還是cglib動態代理。如果在@EnableAspectJAutoProxy(proxyTargetClass = true) 加上屬性,則就會都優先使用cglib的動態代理。


上面分析了得到代理工廠,代理工廠得到得到代理類是getProxy()。代理工廠兩個:JdkDynamicAopProxy,ObjenesisCglibAopProxy。

JdkDynamicAopProxy#getProxy()

jdk動態代理生成的代理類是實現一些指定介面的代理類,實現那些介面是:AopProxyUtils.completeProxiedInterfaces(this.advised, true); 查詢。

    public Object getProxy(@Nullable ClassLoader classLoader) {

//        this.advised 就是ProxyFactory物件
        if (logger.isTraceEnabled()) {
            logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource());
        }
        // 獲取生成代理物件所需要實現的介面
//        如果通過指定了 proxyFactory.addInterface 指定了介面,則算上一個,如果沒有指定則看targetClass 是不是介面  如果是的話這個介面算上一個
//        最後還會加上Spring 自帶的三個介面 SpringProxy(只是標記介面,標記是個AOP代理類)、Advised(可以管理AOP 的通知,在使用代理類的時候可以強轉為它 進行管理)、
//        DecoratingProxy
        Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);

        // 判斷這些介面中有沒有定義equals方法,hashcode方法
        findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
        // 針對所指定的介面生成代理物件,包括使用者所新增的介面以及SpringProxy、Advised、DecoratingProxy
        // 所以生成的代理物件可以強制轉換成任意一個介面型別
        //  用的也是JDK中的代理方式, 傳入了this物件,也就是JdkDynamicAopProxy implements AopProxy, InvocationHandler
        //   呼叫代理類方法的時候,就會走 下面的invoke方法
        return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
    }

Spring中建立AOP代理的方式

上面建立代理類舉例子是通過ProxyFactory來的,在spring中是底層才用到這個類,在spring中有幾種實用的建立AOP代理的方式。

1:通過BeanNameAutoProxyCreator 這個後置處理器,進行自動代理。

看到它繼承了AbstractAutoProxyCreator,父類實現了SmartInstantiationAwareBeanPostProcessor後置處理器,裡面肯定有個postProcessBeforeInstantiation,postProcessAfterInitialization。

在postProcessBeforeInstantiation邏輯中會有判斷是否需要提前建立代理物件的邏輯。還會判斷是否要跳過當前bean的代理邏輯的處理: this.advisedBeans.put(cacheKey, Boolean.FALSE);

public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
        Object cacheKey = getCacheKey(beanClass, beanName);
        if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
            // advisedBeans中存的是當前這個bean需不需要代理
            if (this.advisedBeans.containsKey(cacheKey)) {
                return null;
            }
            // 當前bean是不是不需要進行代理
            if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
                this.advisedBeans.put(cacheKey, Boolean.FALSE);
                return null;
            }
        }
        // 檢視是否需要提前生成代理物件
        // Create proxy here if we have a custom TargetSource.
        // Suppresses unnecessary default instantiation of the target bean:
        // The TargetSource will handle target instances in a custom fashion.
        // 判斷當前beanClass和beanName是否會生成一個TargetSource,如果生成了,就進行代理
        TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
        if (targetSource != null) {
            if (StringUtils.hasLength(beanName)) {
                this.targetSourcedBeans.add(beanName);
            }
            Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
            // 建立一個代理物件
            Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
            this.proxyTypes.put(cacheKey, proxy.getClass());
            return proxy;
        }
        return null;
    }

一般的AOP代理邏輯處理是在postProcessAfterInitialization中的

    // 正常情況進行AOP的地方
    public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
        if (bean != null) {
            Object cacheKey = getCacheKey(bean.getClass(), beanName);
            // earlyProxyReferences中存的是哪些提前進行了AOP的bean,beanName:AOP之前的物件
            // 注意earlyProxyReferences中並沒有存AOP之後的代理物件  BeanPostProcessor
            if (this.earlyProxyReferences.remove(cacheKey) != bean) {
                // 沒有提前進行過AOP,則進行AOP
                return wrapIfNecessary(bean, beanName, cacheKey);
            }
        }
        // 為什麼不返回代理物件呢?
        return bean;   //
    }
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
        // 在當前targetSourcedBeans中存在的bean,表示在例項化之前就產生了代理物件
        if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
            return bean;
        }
        // 當前這個bean不用被代理  this.advisedBean 儲存一個bean需不需要被代理
        if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
            return bean;
        }

        // 先判斷當前bean是不是要進行AOP,比如當前bean的型別是Pointcut、Advice、Advisor AopInfrastructureBean 那就不需要進行AOP
//        shouldSkip  給子類來實現判斷是否需要進行AOP代理
        if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
            this.advisedBeans.put(cacheKey, Boolean.FALSE);
            return bean;
        }

        // Create proxy if we have advice.
        //  這麼說不對: 獲取當前beanClass所匹配的advisors(PointCut+Advice) 或者Advice
        // 也是由子類來實現邏輯的  BeanNameAutoProxyCreator
        // 只是返回一個標記 DO_NOT_PROXY、PROXY_WITHOUT_ADDITIONAL_INTERCEPTORS   看是否需要進行AOP代理
        Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);

        // 如果匹配的advisors不等於null,那麼則進行代理,並返回代理物件
        if (specificInterceptors != DO_NOT_PROXY) {
            this.advisedBeans.put(cacheKey, Boolean.TRUE);
            // 基於bean物件和Advisor建立代理物件
            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;
    }

1.1:定義BeanNameAutoProxyCreator

    // 自動代理 BeanPost
    @Bean
    public BeanNameAutoProxyCreator creator(){
        // BeanPostProcessor
        BeanNameAutoProxyCreator beanNameAutoProxyCreator = new BeanNameAutoProxyCreator();
//        設定要目標bean的beanName,可以配置多個
        beanNameAutoProxyCreator.setBeanNames("userService");  // bean==>AOP
//        設定攔截器名稱,其實就是Advisor= PointCut+Advice
        beanNameAutoProxyCreator.setInterceptorNames("myAdvisor");
        return beanNameAutoProxyCreator;
    }

1.2: 定義Advisor

@Component
public class MyAdvisor implements PointcutAdvisor {
    @Override
    public Pointcut getPointcut() {
//        設定切點資訊,通過方法的名字匹配切點
        NameMatchMethodPointcut pointcut = new NameMatchMethodPointcut();
//        設定了切點為 方法名是test的方法
        pointcut.addMethodName("test");
        return pointcut;
    }

    @Override
    public Advice getAdvice() {
//        設定Advice  增強的邏輯
        return new MethodBeforeAdvice() {
            @Override
            public void before(Method method, Object[] args, Object target) throws Throwable {
                System.out.println("Myadvisor方法執行前"+target.getClass().getName());
            }
        };
    }

    @Override
    public boolean isPerInstance() {
        return false;
    }
}

上面的方式配置的AOP邏輯實現了。

2:還有一種通過DefaultAdvisorAutoProxyCreator來進行AOP邏輯查詢匹配的方式。

@Bean
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator(){
        DefaultAdvisorAutoProxyCreator creator = new DefaultAdvisorAutoProxyCreator();
        return creator;
    }

DefaultAdvisorAutoProxyCreator 是找Advisor型別的bean,然後進行匹配。就是上面自定義的MyAdvisor。

這個Bean可以替換掉上面的那個BeanNameAutoProxyCreator。但是這種方式也不方便,因為定義Advisor不夠靈活,配置比較麻煩。

3:使用註解,這種方式比較常用。@EnableAspectJAutoProxy

這個註解有proxyTargetClass 屬性預設false(如果為true表示要使用cglib的動態代理),exposeProxy 屬性預設為false。

Advisor是通過如下方式:

@Component
@Aspect
public class TestAspect  {
    @Before("execution(public void com.luban.service.UserService.test())")

    public void before(){
        System.out.println("註解前置方法執行");
    }
}

在配置類上加了這個註解之後,這個註解會引入一個類:AspectJAutoProxyRegistrar。和上面的方式相比:

AspectJAutoProxyRegistrar 繼承ImportBeanDefinitionRegistrar ,具有註冊beanDefinition的功能。就是registerBeanDefinitions方法:註冊一個AnnotationAwareAspectJAutoProxyCreator 類。

public void registerBeanDefinitions(
            AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {

//        註冊一個 AnnotationAwareAspectJAutoProxyCreator 的bean
        AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);

        AnnotationAttributes enableAspectJAutoProxy =
                AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
        if (enableAspectJAutoProxy != null) {
            if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
                AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
            }
            if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
                AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
            }
        }
    }

AnnotationAwareAspectJAutoProxyCreator 的繼承結構如上圖,它不僅可以找到Advisor型別的bean,還可以找@Aspect標註的bean。


這種註解方式的執行流程按照上面的繼承關係重新整理一下如下:

1:AbstractAutoProxyCreator

是個bean的後置處理器,在某個bean的建立過程中,會執行它裡面的postProcessBeforeInstantiation,postProcessAfterInitialization

AbstractAutoProxyCreator#postProcessBeforeInstantiation

public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
        Object cacheKey = getCacheKey(beanClass, beanName);
        if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
            // advisedBeans中存的是當前這個bean需不需要代理
            if (this.advisedBeans.containsKey(cacheKey)) {
                return null;
            }
            // 當前bean是不是不需要進行代理 裡面的兩個方法都可以被子類實現,作為自己不同場景下的判斷
            if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
                this.advisedBeans.put(cacheKey, Boolean.FALSE);
                return null;
            }
        }
        // 檢視是否需要提前生成代理物件
        // Create proxy here if we have a custom TargetSource.
        // Suppresses unnecessary default instantiation of the target bean:
        // The TargetSource will handle target instances in a custom fashion.
        // 判斷當前beanClass和beanName是否會生成一個TargetSource,如果生成了,就進行代理
        TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
        if (targetSource != null) {
            if (StringUtils.hasLength(beanName)) {
                this.targetSourcedBeans.add(beanName);
            }
            Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
            // 建立一個代理物件
            Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
            this.proxyTypes.put(cacheKey, proxy.getClass());
            return proxy;
        }
        return null;
    }

上面有兩個方法isInfrastructureClass,shouldSkip可以由子類來判斷一個bean要不要進行代理。

AnnotationAwareAspectJAutoProxyCreator #isInfrastructureClass

protected boolean isInfrastructureClass(Class<?> beanClass) {
        // Previously we setProxyTargetClass(true) in the constructor, but that has too
        // broad an impact. Instead we now override isInfrastructureClass to avoid proxying
        // aspects. I'm not entirely happy with that as there is no good reason not
        // to advise aspects, except that it causes advice invocation to go through a
        // proxy, and if the aspect implements e.g the Ordered interface it will be
        // proxied by that interface and fail at runtime as the advice method is not
        // defined on the interface. We could potentially relax the restriction about
        // not advising aspects in the future.
//        呼叫父類的過濾方法,如果父類沒有過濾掉,呼叫自己增加的增加的過濾方法(過濾掉@Aspect註解標註的bean,因為這是作為Advisor集合的bean)
        return (super.isInfrastructureClass(beanClass) ||
                (this.aspectJAdvisorFactory != null && this.aspectJAdvisorFactory.isAspect(beanClass)));
    }

父類中AbstractAutoProxyCreator#isInfrastructureClass

    protected boolean isInfrastructureClass(Class<?> beanClass) {
//        過濾掉一些 和AOP相關的bean
        boolean retVal = Advice.class.isAssignableFrom(beanClass) ||
                Pointcut.class.isAssignableFrom(beanClass) ||
                Advisor.class.isAssignableFrom(beanClass) ||
                AopInfrastructureBean.class.isAssignableFrom(beanClass);
        if (retVal && logger.isTraceEnabled()) {
            logger.trace("Did not attempt to auto-proxy infrastructure class [" + beanClass.getName() + "]");
        }
        return retVal;
    }

AspectJAwareAdvisorAutoProxyCreator#shouldSkip

    protected boolean shouldSkip(Class<?> beanClass, String beanName) {
        // TODO: Consider optimization by caching the list of the aspect names
        // 得到型別為Advisor的bean,以及被@Aspect註解修飾了的類中所定義的@Before等
        List<Advisor> candidateAdvisors = findCandidateAdvisors();

        // 如果當前beanName是AspectJPointcutAdvisor,那麼則跳過
        for (Advisor advisor : candidateAdvisors) {
            if (advisor instanceof AspectJPointcutAdvisor &&
                    ((AspectJPointcutAdvisor) advisor).getAspectName().equals(beanName)) {
                return true;
            }
        }
//        呼叫父類的的shouldSkip 方法
        return super.shouldSkip(beanClass, beanName);
    }

父類中AbstractAutoProxyCreator#shouldSkip

protected boolean shouldSkip(Class<?> beanClass, String beanName) {
        return AutoProxyUtils.isOriginalInstance(beanName, beanClass);
    }
static boolean isOriginalInstance(String beanName, Class<?> beanClass) {
        if (!StringUtils.hasLength(beanName) || beanName.length() !=
                beanClass.getName().length() + AutowireCapableBeanFactory.ORIGINAL_INSTANCE_SUFFIX.length()) {
            return false;
        }
        return (beanName.startsWith(beanClass.getName()) &&
                beanName.endsWith(AutowireCapableBeanFactory.ORIGINAL_INSTANCE_SUFFIX));
    }

在AspectJAwareAdvisorAutoProxyCreator#shouldSkip中有一個findCandidateAdvisors 的方法,找到所有候選者Advisor

它由子類重寫了,AnnotationAwareAspectJAutoProxyCreator#findCandidateAdvisors如下


    protected List<Advisor> findCandidateAdvisors() {
        // Add all the Spring advisors found according to superclass rules.
        // 先去呼叫父類的 findCandidateAdvisors 方法
        // Advisor=Pointcut+Advice (切點加建議) ,獲得到所有Advisor型別的bean
        List<Advisor> advisors = super.findCandidateAdvisors();

        // Build Advisors for all AspectJ aspects in the bean factory.
        // 找的是通過AspectJ的方式定義的Advisor
        if (this.aspectJAdvisorsBuilder != null) {
            advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
        }
        return advisors;
    }

假如上面例項化之前的那個方法沒有進行Aop代理,那麼正常AOP代理物件是在postProcessAfterInitialization中產生的。

AbstractAutoProxyCreator#postProcessAfterInitialization

public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
        if (bean != null) {
            Object cacheKey = getCacheKey(bean.getClass(), beanName);
            // earlyProxyReferences中存的是哪些提前進行了AOP的bean,beanName:AOP之前的物件
            // 注意earlyProxyReferences中並沒有存AOP之後的代理物件  BeanPostProcessor
            if (this.earlyProxyReferences.remove(cacheKey) != bean) {
                // 沒有提前進行過AOP,則進行AOP
                return wrapIfNecessary(bean, beanName, cacheKey);
            }
        }
        // 為什麼不返回代理物件呢?
        return bean;   //
    }

protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
        // 在當前targetSourcedBeans中存在的bean,表示在例項化之前就產生了代理物件
        if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
            return bean;
        }
        // 當前這個bean不用被代理  this.advisedBean 儲存一個bean需不需要被代理
        if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
            return bean;
        }
        // 先判斷當前bean是不是要進行AOP,比如當前bean的型別是Pointcut、Advice、Advisor AopInfrastructureBean 那就不需要進行AOP
//        shouldSkip  給子類來實現判斷是否需要進行AOP代理
        if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
            this.advisedBeans.put(cacheKey, Boolean.FALSE);
            return bean;
        }

        // Create proxy if we have advice.
        //  這麼說不對: 獲取當前beanClass所匹配的advisors(PointCut+Advice) 或者Advice
        // 也是由子類來實現邏輯的  BeanNameAutoProxyCreator
        // 只是返回一個標記 DO_NOT_PROXY、PROXY_WITHOUT_ADDITIONAL_INTERCEPTORS   看是否需要進行AOP代理
        Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);

        // 如果匹配的advisors不等於null,那麼則進行代理,並返回代理物件
        if (specificInterceptors != DO_NOT_PROXY) {
            this.advisedBeans.put(cacheKey, Boolean.TRUE);
            // 基於bean物件和Advisor建立代理物件
            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#getAdvicesAndAdvisorsForBean
    protected Object[] getAdvicesAndAdvisorsForBean(
            Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {

        // 針對當前bean查詢合格的Advisor
        List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
        if (advisors.isEmpty()) {
            return DO_NOT_PROXY;
        }
        return advisors.toArray();
    }
// 查詢合格的Advisor(和beanClass匹配)
    protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
        // 得到所有的Advisor
        List<Advisor> candidateAdvisors = findCandidateAdvisors();
        // 進行篩選 篩選和beanClass匹配的Advisor
        List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);

        // 提供給子類去額外的新增advisor
        extendAdvisors(eligibleAdvisors);
        if (!eligibleAdvisors.isEmpty()) {
            // 按order進行排序
            eligibleAdvisors = sortAdvisors(eligibleAdvisors);
        }

        // 返回匹配的Advisor
        return eligibleAdvisors;
    }
    protected List<Advisor> findCandidateAdvisors() {
        // Add all the Spring advisors found according to superclass rules.
        // 先去呼叫父類的 findCandidateAdvisors 方法
        // Advisor=Pointcut+Advice (切點加建議) ,獲得到所有Advisor型別的bean
        List<Advisor> advisors = super.findCandidateAdvisors();

        // Build Advisors for all AspectJ aspects in the bean factory.
        // 找的是通過AspectJ的方式定義的Advisor   找到@Aspect註解標註的類
        if (this.aspectJAdvisorsBuilder != null) {
            advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
        }
        return advisors;
    }
進行建立代理的邏輯:createProxy
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 = new ProxyFactory();
        proxyFactory.copyFrom(this);    // 複製配置引數
        // 是否指定了必須用cglib進行代理
        if (!proxyFactory.isProxyTargetClass()) {
            // 如果沒有指定,那麼則判斷是不是應該進行cglib代理(判斷BeanDefinition中是否指定了要用cglib)
            if (shouldProxyTargetClass(beanClass, beanName)) {
                proxyFactory.setProxyTargetClass(true);
            }
            else {
                // 是否進行jdk動態代理,如果當前beanClass實現了某個介面,那麼則會使用JDK動態代理
                evaluateProxyInterfaces(beanClass, proxyFactory); // 判斷beanClass有沒有實現介面
            }
        }


        // 將commonInterceptors和specificInterceptors整合再一起
        Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);

        proxyFactory.addAdvisors(advisors);    // 向ProxyFactory中新增advisor
        proxyFactory.setTargetSource(targetSource); // 被代理的物件
        customizeProxyFactory(proxyFactory);

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

        // 生成代理物件
        return proxyFactory.getProxy(getProxyClassLoader());
    }

首先建立ProxyFactory物件,開頭已經介紹過這個類了。

public void copyFrom(ProxyConfig other) {
        Assert.notNull(other, "Other ProxyConfig object must not be null");
        this.proxyTargetClass = other.proxyTargetClass;  // 是否開啟cglib
        this.optimize = other.optimize;
        this.exposeProxy = other.exposeProxy; // 是否將生成的代理物件設定到AopContext中去,後面可以通過AopContext.currentProxy()拿到
        this.frozen = other.frozen;
        this.opaque = other.opaque;
    }
從上面可以看出,是否要用cglib進行代理,不止是看目標物件是否實現了某個介面,還和proxyTargetClass屬性有關,這個屬性在 @EnableAspectJAutoProxy中有設定,注入AnnotationAwareAspectJAutoProxyCreator的時候賦值進去的,然而看上面的邏輯,就算是
沒有設定,還會判斷當前bean對應的BeanDefinition中是否有設定一個名為:org.springframework.aop.framework.autoproxy.AutoProxyUtils.preserveTargetClass=true的屬性,如果有的話也會設定為true。

getProxy中,會先判斷使用JDK代理工廠還是使用cglib的代理工廠

    public Object getProxy(@Nullable ClassLoader classLoader) {
        // 根據不同的情況得到不同的動態代理工廠,cglib或jdk動態代理
        return createAopProxy().getProxy(classLoader);
    }
    protected final synchronized AopProxy createAopProxy() {
        if (!this.active) {
            activate();
        }
        // 預設用的就是DefaultAopProxyFactory
        return getAopProxyFactory().createAopProxy(this);
    }

AopProxy有兩種,一種是JdkDynamicAopProxy,一種是CglibAopProxy

JdkDynamicAopProxy#getProxy

    public Object getProxy(@Nullable ClassLoader classLoader) {

//        this.advised 就是ProxyFactory物件
        if (logger.isTraceEnabled()) {
            logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource());
        }
        // 獲取生成代理物件所需要實現的介面
//        如果通過指定了 proxyFactory.addInterface 指定了介面,則算上一個,如果沒有指定則看targetClass 是不是介面  如果是的話這個介面算上一個
//        最後還會加上Spring 自帶的三個介面 SpringProxy(只是標記介面,標記是個AOP代理類)、Advised(可以管理AOP 的通知,在使用代理類的時候可以強轉為它 進行管理)、
//        DecoratingProxy
        Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);

        // 判斷這些介面中有沒有定義equals方法,hashcode方法
        findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
        // 針對所指定的介面生成代理物件,包括使用者所新增的介面以及SpringProxy、Advised、DecoratingProxy
        // 所以生成的代理物件可以強制轉換成任意一個介面型別
        //  用的也是JDK中的代理方式, 傳入了this物件,也就是JdkDynamicAopProxy implements AopProxy, InvocationHandler
        //   呼叫代理類方法的時候,就會走 下面的invoke方法
        return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
    }
JdkDynamicAopProxy 本身是一個InvocationHandler,所以當呼叫目標物件的方法時就會執行JdkDynamicAopProxy#invoke方法。
裡面主要的邏輯如下:
上面的 this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);,會得到那些在@Aspect中定義的Advice。這些Advice根據@Before,@After等等的不同,分為AspectJAroundAdvice等等。

然後把這個執行鏈,還有代理物件,目標物件封裝成 ReflectiveMethodInvocation,然後執行其proceed方法,這個方法是個遞迴呼叫。
public Object proceed() throws Throwable {
        // We start with an index of -1 and increment early.
//        this.currentInterceptorIndex  預設=-1
        if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
// 最後執行method本身的邏輯
return invokeJoinpoint(); } Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex); if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) { // Evaluate dynamic method matcher here: static part will already have // been evaluated and found to match. InterceptorAndDynamicMethodMatcher dm = (InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice; Class<?> targetClass = (this.targetClass != null ? this.targetClass : this.method.getDeclaringClass()); if (dm.methodMatcher.matches(this.method, targetClass, this.arguments)) { return dm.interceptor.invoke(this); } else { // Dynamic matching failed. // Skip this interceptor and invoke the next in the chain. return proceed(); } } else { // It's an interceptor, so we just invoke it: The pointcut will have // been evaluated statically before this object was constructed. // 呼叫 AspectJAroundAdvice,AspectJAfterReturningAdvice 等 return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this); } }
以MethodBeforeAdviceInterceptor#invoke為例子
    public Object invoke(MethodInvocation mi) throws Throwable {
// 先執行@Aspect中@Before標註的方法
this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
// 然後繼續呼叫下一個Advice方法
return mi.proceed(); // methodinter target.test(); }
在ReflectiveAspectJAdvisorFactory#getAdvisor 中把上面@Aspect的類中的方法封裝成Advisor物件。
    public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory,
            int declarationOrderInAspect, String aspectName) {

        validate(aspectInstanceFactory.getAspectMetadata().getAspectClass());
        // 得到當前candidateAdviceMethod方法上的所定義的expression表示式,也就是切點
        AspectJExpressionPointcut expressionPointcut = getPointcut(
                candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass());
        if (expressionPointcut == null) {
            return null;
        }
        // 構造一個Advisor,封裝了切點表示式和當前方法
        return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod,
                this, aspectInstanceFactory, declarationOrderInAspect, aspectName);
    }

不同的Advice對應的不同的類,就是上面說的MethodInterceptor.