Spring AOP源碼詳細解析

一 . 以下是bean的初始化過程: 

注意: 先明白beanPostProcessor的作用,才能夠明白aop的加載時機

在bean實例化完成之前和完成之後分別會自動BeanPostProcessor接口的postProcessBeforeInitialization和postProcessAfterInitialization方法。

 

二: 介紹一些Spring Aop中一些核心類,大致分爲三類:

    advisorCreator,繼承 spring ioc的擴展接口 beanPostProcessor,主要用來掃描獲取 advisor。

    beanPostProcessor作用: Spring容器中完成bean實例化、配置以及其他初始化方法前後要添加一些自己邏輯處理。

                                                 我們需要定義一個或多個BeanPostProcessor接口實現類,然後註冊到Spring IoC容器中。
    advisor:顧問的意思,封裝了spring aop中的切點和通知。 就是我們常用的@Aspect 註解標記得類
    advice:通知,也就是aop中增強的方法。

advisorCreator:

  

 

AbstractAutoProxyCreator:Spring 爲Spring AOP 模塊暴露的可擴展抽象類,也是 AOP 中最核心的抽象類。Nepxion Matrix 框架便是基於此類對AOP進行擴展和增強。

BeanNameAutoProxyCreator:根據指定名稱創建代理對象(阿里大名鼎鼎的連接池框架druid也基於此類做了擴展)。通過設置 advisor,可以對指定的 beanName 進行代理。支持模糊匹配。

AbstractAdvisorAutoProxyCreator:功能比較強大,默認掃描所有Advisor的實現類。相對於根據Bean名稱匹配,該類更加靈活。動態的匹配每一個類,判斷是否可以被代理,並尋找合適的增強類,以及生成代理類。

DefaultAdvisorAutoProxyCreator:AbstractAdvisorAutoProxyCreator的默認實現類。可以單獨使用,在框架中使用AOP,儘量不要手動創建此對象。

AspectJAwareAdvisorAutoProxyCreator:Aspectj的實現方式,也是Spring Aop中最常用的實現方式,如果用註解方式,則用其子類AnnotationAwareAspectJAutoProxyCreator。

AnnotationAwareAspectJAutoProxyCreator:目前最常用的AOP使用方式。spring aop 開啓註解方式之後,該類會掃描所有@Aspect()註釋的類,生成對應的advisor。目前SpringBoot框架中默認支持的方式,自動配置。
 

     圖片來自於: https://www.cnblogs.com/yuxiang1/archive/2018/06/19/9199730.html

 

三. spring實現AOP思路:

      1: 創建AnnotationAwareAspectJAutoProxyCreator對象
      2: 掃描容器中的切面,創建PointcutAdvisor對象
      3: 生成代理類

 

四 .介紹AbstractAutoProxyCreator中判斷是否生成代理類以及

       創建PointcutAdvisor對象的過程:

可以看到在AbstractAutoProxyCreator類中的上層接口實現了BeanPostProcessor接口,

對於下面兩個方法, 重寫的第一個方法,其主要目的在於如果用戶使用了自定義的TargetSource對象,則直接使用該對象生成目標對象,而不會使用Spring的默認邏輯生成目標對象,並且這裏會判斷各個切面邏輯是否可以應用到當前bean上,如果可以,則直接應用,也就是說TargetSource爲使用者在Aop中提供了一個自定義生成目標bean邏輯的方式,並且會應用相應的切面邏輯。對於第二個方法,其主要作用在於Spring生成某個bean之後,將相關的切面邏輯應用到該bean上,

瞭解細緻的TargetSource原理請參考: https://blog.csdn.net/zxfryp909012366/article/details/82881659

1. 以下是bean實例化之後, 初始化之前操作postProcessBeforeInstantiation

 在AbstractAutoProxyCreator類中實現BeanPostProcessor中的下面方法中:

 
  1. @Override

  2. public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {

  3. Object cacheKey = getCacheKey(beanClass, beanName);

  4.  
  5. if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {

  6. //advisedBeans用於存儲不可代理的bean,如果包含直接返回

  7. if (this.advisedBeans.containsKey(cacheKey)) {

  8. return null;

  9. }

  10. //判斷當前bean是否可以被代理,然後存入advisedBeans

  11. if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {

  12. this.advisedBeans.put(cacheKey, Boolean.FALSE);

  13. return null;

  14. }

  15. }

  16.  
  17. // Create proxy here if we have a custom TargetSource.

  18. // Suppresses unnecessary default instantiation of the target bean:

  19. // The TargetSource will handle target instances in a custom fashion.

  20. //獲取封裝當前bean的TargetSource對象,如果不存在,則直接退出當前方法,否則從TargetSource

  21. // 中獲取當前bean對象,並且判斷是否需要將切面邏輯應用在當前bean上。

  22. TargetSource targetSource = getCustomTargetSource(beanClass, beanName);

  23. if (targetSource != null) {

  24. if (StringUtils.hasLength(beanName)) {

  25. this.targetSourcedBeans.add(beanName);

  26. }

  27. // 獲取能夠應用當前bean的切面邏輯

  28. Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);

  29. Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);

  30.  
  31. // 對生成的代理對象進行緩存

  32. this.proxyTypes.put(cacheKey, proxy.getClass());

  33. //如果最終可以獲得代理類,則返回代理類,直接執行實例化後置通知方法

  34. return proxy;

  35. }

  36.  
  37. return null;

  38. }

 

================================================================================================

2. 以下是bean初始完成之後創建代理對象過程:postProcessAfterInitialization

在AbstractAutoProxyCreator類中實現BeanPostProcessor中的下面方法中:

 
  1. public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {

  2. if (bean != null) {

  3. //緩存鍵:1.beanName不爲空的話,使用beanName(FactoryBean會在見面加上"&")

  4. //2.如果beanName爲空,使用Class對象作爲緩存的key

  5. Object cacheKey = getCacheKey(bean.getClass(), beanName);

  6. if (!this.earlyProxyReferences.contains(cacheKey)) {

  7. //如果條件符合,則爲bean生成代理對象

  8. return wrapIfNecessary(bean, beanName, cacheKey);

  9. }

  10. }

  11. return bean;

  12. }

 wrapIfNecessary

   代碼流程:

   1.  如果已經處理過,且該bean沒有被代理過,則直接返回該bean
   2.如果該bean是內部基礎設置類Class 或 配置了該bean不需要代理,則直接返回bean(返回前標記該bean已被處理過)
   3.獲取所有適合該bean的增強Advisor
    如果增強不爲null,則爲該bean創建代理對象,並返回結果
    標記該bean已經被處理過

 
  1. protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {

  2. //如果已經處理過(targetSourcedBeans存放已經增強過的bean)

  3. if (beanName != null && this.targetSourcedBeans.contains(beanName)) {

  4. return bean;

  5. }

  6. //advisedBeans的key爲cacheKey,value爲boolean類型,表示是否進行過代理

  7. //已經處理過的bean,不需要再次進行處理,節省時間

  8. if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {

  9. return bean;

  10. }

  11. //是否是內部基礎設置類Class || 配置了指定bean不需要代理,如果是的話,直接緩存。

  12. if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {

  13. this.advisedBeans.put(cacheKey, Boolean.FALSE);

  14. return bean;

  15. }

  16.  
  17. // 獲取當前對象所有適用的Advisor.加入當前對象是orderController,那麼找到所有切點是他的對應的@Aspect註解的類

  18. Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);

  19. //如果獲取的增強不爲null,則爲該bean創建代理(DO_NOT_PROXY=null)

  20. if (specificInterceptors != DO_NOT_PROXY) {

  21. this.advisedBeans.put(cacheKey, Boolean.TRUE);

  22. //創建代理對象時候會用到是否進行JDK代理或者CGLIB代理

  23. Object proxy = createProxy(

  24. bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));

  25. this.proxyTypes.put(cacheKey, proxy.getClass());

  26. return proxy;

  27. }

  28. //標記該cacheKey已經被處理過

  29. this.advisedBeans.put(cacheKey, Boolean.FALSE);

  30. return bean;

  31. }

 

AspectJAwareAdvisorAutoProxyCreator的實現wrapIfNecessary方法中判斷是否爲基礎類的方法:

 
  1. protected boolean isInfrastructureClass(Class<?> beanClass) {

  2. //如果bean繼承自Advice、Pointcut、Advisor、AopInfrastructureBean

  3. boolean retVal = Advice.class.isAssignableFrom(beanClass) ||

  4. Pointcut.class.isAssignableFrom(beanClass) ||

  5. Advisor.class.isAssignableFrom(beanClass) ||

  6. AopInfrastructureBean.class.isAssignableFrom(beanClass);

  7. if (retVal && logger.isTraceEnabled()) {

  8. logger.trace("Did not attempt to auto-proxy infrastructure class [" + beanClass.getName() + "]");

  9. }

  10. return retVal;

  11. }

從上面代碼可以看出,繼承自Advice、Pointcut、Advisor、AopInfrastructureBean無法被增強

AnnotationAwareAspectJAutoProxyCreator 繼承了AspectJAwareAdvisorAutoProxyCreator 類 調用父類方法時候

  在isInfrastructureClass時候,同時加了isAspect方法實現:

 
  1. public boolean isAspect(Class<?> clazz) {

  2. //如果bean帶有@Aspect註解,或被Ajc(AspectJ編譯器)編譯

  3. return (hasAspectAnnotation(clazz) && !compiledByAjc(clazz));

  4. }

綜上,如果一個bean繼承自Advice、Pointcut、Advisor、AopInfrastructureBean 或者 帶有@Aspect註解,或被Ajc(AspectJ編譯器)編譯都會被認定爲內部基礎設置類

在AnnotationUtils類中的findAnnotation方法中,判斷這個bean上的註解類型是不是@Aspect

   以上②邏輯原文: https://blog.csdn.net/finalcola/article/details/82108745

 同時AspectJAwareAdvisorAutoProxyCreator的實現wrapIfNecessary方法中判斷是否要進行代理的方法getAdvicesAndAdvisorsForBean同時會調用

findEligibleAdvisors處理兩件事:

  • findCandidateAdvisors找到Spring中所有的Advisor.
  • findAdvisorsThatCanApply過濾出適合當前對象的advisors
 
  1. protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {

  2.  
  3. //找到Spring中Advisor的實現類(findCandidateAdvisors)

  4. //將所有擁有@Aspect註解的類轉換爲advisors(aspectJAdvisorsBuilder.buildAspectJAdvisors)

  5. List<Advisor> candidateAdvisors = findCandidateAdvisors();

  6.  
  7. /* findAdvisorsThatCanApply

  8. 找到當前對象適合的所有Advisor。整個過程比較簡單:

  9. 遍歷所有的advisor。

  10. 查看當前advisor的pointCut是否適用於當前對象,如果是,進入候選隊列,否則跳過。*/

  11.  
  12. List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);

  13. //添加一個默認的advisor,執行時用到。

  14. extendAdvisors(eligibleAdvisors);

  15. if (!eligibleAdvisors.isEmpty()) {

  16. eligibleAdvisors = sortAdvisors(eligibleAdvisors);

  17. }

  18. return eligibleAdvisors;

  19. }

 

 findCandidateAdvisors:

 
  1. protected List<Advisor> findCandidateAdvisors() {

  2. // Add all the Spring advisors found according to superclass rules.

  3. List<Advisor> advisors = super.findCandidateAdvisors();

  4. // Build Advisors for all AspectJ aspects in the bean factory.

  5. advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());

  6. return advisors;

  7. }

 super.findCandidateAdvisors()方法最終調用的是BeanFactoryAdvisorRetrievalHelper.findAdvisorBeans()方法,我們首先看看該方法的實現:

 
  1. public List<Advisor> findAdvisorBeans() {

  2. String[] advisorNames = null;

  3. synchronized (this) {

  4. advisorNames = this.cachedAdvisorBeanNames;

  5. if (advisorNames == null) {

  6. // 獲取當前BeanFactory中所有實現了Advisor接口的bean的名稱

  7. advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(

  8. this.beanFactory, Advisor.class, true, false);

  9. this.cachedAdvisorBeanNames = advisorNames;

  10. }

  11. }

  12. if (advisorNames.length == 0) {

  13. return new LinkedList<>();

  14. }

  15.  
  16. // 對獲取到的實現Advisor接口的bean的名稱進行遍歷

  17. List<Advisor> advisors = new LinkedList<>();

  18. for (String name : advisorNames) {

  19. // isEligibleBean()是提供的一個hook方法,用於子類對Advisor進行過濾,這裏默認返回值都是true

  20. if (isEligibleBean(name)) {

  21. // 如果當前bean還在創建過程中,則略過,其創建完成之後會爲其判斷是否需要織入切面邏輯

  22. if (this.beanFactory.isCurrentlyInCreation(name)) {

  23. if (logger.isDebugEnabled()) {

  24. logger.debug("Skipping currently created advisor '" + name + "'");

  25. }

  26. } else {

  27. try {

  28. // 將當前bean添加到結果中

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

  30. } catch (BeanCreationException ex) {

  31. // 對獲取過程中產生的異常進行封裝

  32. Throwable rootCause = ex.getMostSpecificCause();

  33. if (rootCause instanceof BeanCurrentlyInCreationException) {

  34. BeanCreationException bce = (BeanCreationException) rootCause;

  35. String bceBeanName = bce.getBeanName();

  36. if (bceBeanName != null &&

  37. this.beanFactory.isCurrentlyInCreation(bceBeanName)) {

  38. if (logger.isDebugEnabled()) {

  39. logger.debug("Skipping advisor '" + name +

  40. "' with dependency on currently created bean: "

  41. + ex.getMessage());

  42. }

  43. continue;

  44. }

  45. }

  46. throw ex;

  47. }

  48. }

  49. }

  50. }

  51. return advisors;

  52. }

 

   然後其中的 buildAspectJAdvisors方法,會觸發ReflectiveAspectJAdvisorFactory中的getAdvisors方法:

 
  1. @Override

  2. public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {

  3. //從 aspectMetadata 中獲取 Aspect()標註的類 class對象

  4. Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();

  5. //獲取Aspect()標註的類名

  6. String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName();

  7. validate(aspectClass);

  8.  
  9. // We need to wrap the MetadataAwareAspectInstanceFactory with a decorator

  10. // so that it will only instantiate once.

  11. MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory =

  12. new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory);

  13.  
  14. List<Advisor> advisors = new LinkedList<>();

  15. //遍歷該類所有方法,根據方法判斷是否能獲取到對應 pointCut,如果有,則生成 advisor 對象

  16. for (Method method : getAdvisorMethods(aspectClass)) {

  17. //這裏繼續看下面的解析

  18. Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName);

  19. if (advisor != null) {

  20. advisors.add(advisor);

  21. }

  22. }

  23.  
  24. // If it's a per target aspect, emit the dummy instantiating aspect.

  25. if (!advisors.isEmpty() && lazySingletonAspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {

  26. Advisor instantiationAdvisor = new SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory);

  27. advisors.add(0, instantiationAdvisor);

  28. }

  29.  
  30. // Find introduction fields.

  31. //獲取 @DeclareParents 註解修飾的屬性(並不常用)

  32. for (Field field : aspectClass.getDeclaredFields()) {

  33. Advisor advisor = getDeclareParentsAdvisor(field);

  34. if (advisor != null) {

  35. advisors.add(advisor);

  36. }

  37. }

  38.  
  39. return advisors;

  40. }

 繼續來看getAdvisor方法:

 
  1. @Override

  2. @Nullable

  3. public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory,

  4. int declarationOrderInAspect, String aspectName) {

  5.  
  6. validate(aspectInstanceFactory.getAspectMetadata().getAspectClass());

  7. //根據候選方法名,來獲取對應的 pointCut

  8. AspectJExpressionPointcut expressionPointcut = getPointcut(

  9. candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass());

  10. if (expressionPointcut == null) {

  11. return null;

  12. }

  13. //如果能獲取到 pointCut,則將切點表達式 expressionPointcut、當前

  14. 對象ReflectiveAspectJAdvisorFactory、 方法名等包裝成 advisor 對象

  15. return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod,

  16. this, aspectInstanceFactory, declarationOrderInAspect, aspectName);

  17. }

InstantiationModelAwarePointcutAdvisorImpl的構造方法會觸發構造通知對象:

 
  1. public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut,

  2. MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {

  3. //......

  4. //根據註解類型,匹配對應的通知類型

  5. switch (aspectJAnnotation.getAnnotationType()) {

  6. //前置通知

  7. case AtBefore:

  8. springAdvice = new AspectJMethodBeforeAdvice(

  9. candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);

  10. break;

  11. //最終通知

  12. case AtAfter:

  13. springAdvice = new AspectJAfterAdvice(

  14. candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);

  15. break;

  16. //後置通知

  17. case AtAfterReturning:

  18. springAdvice = new AspectJAfterReturningAdvice(

  19. candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);

  20. AfterReturning afterReturningAnnotation = (AfterReturning) aspectJAnnotation.getAnnotation();

  21. if (StringUtils.hasText(afterReturningAnnotation.returning())) {

  22. springAdvice.setReturningName(afterReturningAnnotation.returning());

  23. }

  24. break;

  25. //異常通知

  26. case AtAfterThrowing:

  27. springAdvice = new AspectJAfterThrowingAdvice(

  28. candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);

  29. AfterThrowing afterThrowingAnnotation = (AfterThrowing) aspectJAnnotation.getAnnotation();

  30. if (StringUtils.hasText(afterThrowingAnnotation.throwing())) {

  31. springAdvice.setThrowingName(afterThrowingAnnotation.throwing());

  32. }

  33. break;

  34. //環繞通知

  35. case AtAround:

  36. springAdvice = new AspectJAroundAdvice(

  37. candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);

  38. break;

  39. //切面

  40. case AtPointcut:

  41. if (logger.isDebugEnabled()) {

  42. logger.debug("Processing pointcut '" + candidateAdviceMethod.getName() + "'");

  43. }

  44. return null;

  45. default:

  46. throw new UnsupportedOperationException(

  47. "Unsupported advice type on method: " + candidateAdviceMethod);

  48. }

  49.  
  50. //......

  51. }

 

可以看到,根據@Aspect類中方法的註解類型,生成對應的advice,並通過通知的構造方法,將通知增強方法,切面表達式傳入到通知當中。

到這裏InstantiationModelAwarePointcutAdvisorImpl對象構造完畢。

 

五 .介紹AbstractAutoProxyCreator中創建代理對象的過程:

原文:https://blog.csdn.net/uftjtt/article/details/80076733

Spring XML關於ProxyFactoryBean使用配置:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop.xsd">
    <!-- 業務Bean -->
    <bean name="conferenceService" class="com.lanhuigu.spring.ConferenceServiceImpl"></bean>
 
    <!--配置Advice-->
    <bean name="logAdvice" class="com.lanhuigu.spring.aop.LoggerAdvice"></bean>
 
    <!--配置ProxyFactoryBean-->
    <bean name="aopMethod" class="org.springframework.aop.framework.ProxyFactoryBean">
        <!-- 指定通知器 -->
        <property name="interceptorNames">
            <list>
                <value>logAdvice</value>
            </list>
        </property>
        <!-- 需要增強的類 -->
        <property name="target" ref="conferenceService"/>
    </bean>
 
</beans>

AopProxy代理對象的生成過程:

 

 

 最後我們回到最初的AbstractAutoProxyCreator中的createProxy方法中

 
  1. protected Object createProxy(Class<?> beanClass, @Nullable String beanName,

  2. @Nullable Object[] specificInterceptors, TargetSource targetSource) {

  3.  
  4. if (this.beanFactory instanceof ConfigurableListableBeanFactory) {

  5. AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);

  6. }

  7.  
  8. ProxyFactory proxyFactory = new ProxyFactory();

  9. //獲取當前類中的屬性

  10. proxyFactory.copyFrom(this);

  11. //檢查proxyTargeClass設置以及preserveTargetClass屬性

  12. //決定對於給定的bean是否應該使用targetClass而不是他的接口代理

  13. if (!proxyFactory.isProxyTargetClass()) {

  14. if (shouldProxyTargetClass(beanClass, beanName)) {

  15. proxyFactory.setProxyTargetClass(true);

  16. }

  17. else {

  18. //用來添加代理接口

  19. evaluateProxyInterfaces(beanClass, proxyFactory);

  20. }

  21. }

  22.  
  23. Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);

  24. //加入增強器

  25. proxyFactory.addAdvisors(advisors);

  26. //設置要代理的類

  27. proxyFactory.setTargetSource(targetSource);

  28. //定製代理

  29. customizeProxyFactory(proxyFactory);

  30. //用來控制代理工廠被設置後是否還允許修改通知,缺省值爲false

  31. proxyFactory.setFrozen(this.freezeProxy);

  32. if (advisorsPreFiltered()) {

  33. proxyFactory.setPreFiltered(true);

  34. }

  35.  
  36. return proxyFactory.getProxy(getProxyClassLoader());

  37. }

從上面代碼我們看到對於代理類的創建及處理spring是委託給了ProxyFactory處理的,而在此函數中主要是對ProxyFactory的初始化操作,進而對創建代理做準備,這些初始化操作包括以下內容:
(1)獲取當前類中的屬性
(2)添加代理接口

下面是添加代理接口evaluateProxyInterfaces的函數:

 
  1. protected void evaluateProxyInterfaces(Class<?> beanClass, ProxyFactory proxyFactory) {

  2. Class<?>[] targetInterfaces = ClassUtils.getAllInterfacesForClass(beanClass, getProxyClassLoader());

  3. boolean hasReasonableProxyInterface = false;

  4. for (Class<?> ifc : targetInterfaces) {

  5. if (!isConfigurationCallbackInterface(ifc) && !isInternalLanguageInterface(ifc) &&

  6. ifc.getMethods().length > 0) {

  7. hasReasonableProxyInterface = true;

  8. break;

  9. }

  10. }

  11. if (hasReasonableProxyInterface) {

  12. // Must allow for introductions; can't just set interfaces to the target's interfaces only.

  13. for (Class<?> ifc : targetInterfaces) {

  14. proxyFactory.addInterface(ifc);

  15. }

  16. }

  17. else {

  18. proxyFactory.setProxyTargetClass(true);

  19. }

  20. }

(3)封裝Advisor並加入到ProxyFactory中
(4)設置要代理的類
(5)在spring中還爲子類提供了定製的函數customizeProxyFactory,子類可以在此函數中進行對ProxyFactory的進一步封裝
(6)進行獲取代理操作

在createProxy方法最後返回的getProxy方法中可以看到

 
  1. public Object getProxy(@Nullable ClassLoader classLoader) {

  2. return createAopProxy().getProxy(classLoader);

  3. }

在上面的getProxy方法中createAopProxy方法,其實現是在DefaultAopProxyFactory中,我們進入到方法內:

 
  1. @Override

  2. public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {

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

  4. Class<?> targetClass = config.getTargetClass();

  5. if (targetClass == null) {

  6. throw new AopConfigException("TargetSource cannot determine target class: " +

  7. "Either an interface or a target is required for proxy creation.");

  8. }

  9. if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {

  10. return new JdkDynamicAopProxy(config);

  11. }

  12. return new ObjenesisCglibAopProxy(config);

  13. }

  14. else {

  15. return new JdkDynamicAopProxy(config);

  16. }

  17. }

 

六: Spring Boot 1.x 版本和 2.x版本 AOP 默認配置的變動

配置類AopAutoConfiguration:

1.5x版本:

    @Configuration
    @EnableAspectJAutoProxy(proxyTargetClass = true)
    @ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true", matchIfMissing = false)
    public static class CglibAutoProxyConfiguration {

    }

2.x版本:

    @Configuration
    @EnableAspectJAutoProxy(proxyTargetClass = true)
    @ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true", matchIfMissing = true)
    public static class CglibAutoProxyConfiguration {

    }

可以看到,在SpringBoot2.x中最主要的變化就是proxy-target-class默認爲true,意味着類代理的時候全部走cglib代理方式,只有爲接口代理時才走jdk代理(注意:這裏爲接口代理,不是指代理目標類是否實現了接口)。所以,在使用springboot2.x的版本中,除了代理目標類是接口外,其餘的代理方式全部採用cglib類型。
總結

Springboot通過自動裝配AopAutoConfiguration配置類,默認自動開啓 AOP 功能。通過註冊 AnnotationAwareAspectJAutoProxyCreator類,來掃描創建所有的Advisor,再通過 Advisor在 Spring IOC的擴展接口中來創建代理類。