Spring AOP源碼詳細解析

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

注意: 先明白beanPostProcessor的做用,纔可以明白aop的加載時機html

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

 

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

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

    beanPostProcessor做用: Spring容器中完成bean實例化、配置以及其餘初始化方法先後要添加一些本身邏輯處理。緩存

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

advisorCreator:

 

 

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

BeanNameAutoProxyCreator:根據指定名稱建立代理對象(阿里大名鼎鼎的鏈接池框架druid也基於此類作了擴展)。經過設置 advisor,能夠對指定的 beanName 進行代理。支持模糊匹配。ide

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

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

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

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中的下面方法中:

@Override
	public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
		Object cacheKey = getCacheKey(beanClass, beanName);

		if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
			//advisedBeans用於存儲不可代理的bean,若是包含直接返回
			if (this.advisedBeans.containsKey(cacheKey)) {
				return null;
			}
			//判斷當前bean是否能夠被代理,而後存入advisedBeans
			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.
		//獲取封裝當前bean的TargetSource對象,若是不存在,則直接退出當前方法,不然從TargetSource
               // 中獲取當前bean對象,而且判斷是否須要將切面邏輯應用在當前bean上。
		TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
		if (targetSource != null) {
			if (StringUtils.hasLength(beanName)) {
				this.targetSourcedBeans.add(beanName);
			}
                        // 獲取可以應用當前bean的切面邏輯
			Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
			Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);

                        // 對生成的代理對象進行緩存
			this.proxyTypes.put(cacheKey, proxy.getClass());
			//若是最終能夠得到代理類,則返回代理類,直接執行實例化後置通知方法
			return proxy;
		}

		return null;
	}

 

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

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

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

public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		if (bean != null) {
			//緩存鍵:1.beanName不爲空的話,使用beanName(FactoryBean會在見面加上"&")
			//2.若是beanName爲空,使用Class對象做爲緩存的key
			Object cacheKey = getCacheKey(bean.getClass(), beanName);
			if (!this.earlyProxyReferences.contains(cacheKey)) {
				//若是條件符合,則爲bean生成代理對象
				return wrapIfNecessary(bean, beanName, cacheKey);
			}
		}
		return bean;
	}

 wrapIfNecessary

   代碼流程:

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

protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
		//若是已經處理過(targetSourcedBeans存放已經加強過的bean)
		if (beanName != null && this.targetSourcedBeans.contains(beanName)) {
			return bean;
		}
		//advisedBeans的key爲cacheKey,value爲boolean類型,表示是否進行過代理
		//已經處理過的bean,不須要再次進行處理,節省時間
		if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
			return bean;
		}
		//是不是內部基礎設置類Class || 配置了指定bean不須要代理,若是是的話,直接緩存。
		if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
			this.advisedBeans.put(cacheKey, Boolean.FALSE);
			return bean;
		}
 
		// 獲取當前對象全部適用的Advisor.加入當前對象是orderController,那麼找到全部切點是他的對應的@Aspect註解的類
		Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
		//若是獲取的加強不爲null,則爲該bean建立代理(DO_NOT_PROXY=null)
		if (specificInterceptors != DO_NOT_PROXY) {
			this.advisedBeans.put(cacheKey, Boolean.TRUE);
                        //建立代理對象時候會用到是否進行JDK代理或者CGLIB代理
			Object proxy = createProxy(
					bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
			this.proxyTypes.put(cacheKey, proxy.getClass());
			return proxy;
		}
		//標記該cacheKey已經被處理過
		this.advisedBeans.put(cacheKey, Boolean.FALSE);
		return bean;
	}

 

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

protected boolean isInfrastructureClass(Class<?> beanClass) {
		//若是bean繼承自Advice、Pointcut、Advisor、AopInfrastructureBean
		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;
	}

從上面代碼能夠看出,繼承自Advice、Pointcut、Advisor、AopInfrastructureBean沒法被加強

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

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

public boolean isAspect(Class<?> clazz) {
		//若是bean帶有@Aspect註解,或被Ajc(AspectJ編譯器)編譯
		return (hasAspectAnnotation(clazz) && !compiledByAjc(clazz));
	}

綜上,若是一個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
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
         
        //找到Spring中Advisor的實現類(findCandidateAdvisors)
        //將全部擁有@Aspect註解的類轉換爲advisors(aspectJAdvisorsBuilder.buildAspectJAdvisors)
        List<Advisor> candidateAdvisors = findCandidateAdvisors();

       /* findAdvisorsThatCanApply
        找到當前對象適合的全部Advisor。整個過程比較簡單:
        遍歷全部的advisor。
         查看當前advisor的pointCut是否適用於當前對象,若是是,進入候選隊列,不然跳過。*/

        List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
        //添加一個默認的advisor,執行時用到。
        extendAdvisors(eligibleAdvisors);
        if (!eligibleAdvisors.isEmpty()) {
            eligibleAdvisors = sortAdvisors(eligibleAdvisors);
        }
        return eligibleAdvisors;
    }

 

 findCandidateAdvisors:

protected List<Advisor> findCandidateAdvisors() {
        // Add all the Spring advisors found according to superclass rules.
        List<Advisor> advisors = super.findCandidateAdvisors();
        // Build Advisors for all AspectJ aspects in the bean factory.
        advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
        return advisors;
    }

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

public List<Advisor> findAdvisorBeans() {
    String[] advisorNames = null;
    synchronized (this) {
        advisorNames = this.cachedAdvisorBeanNames;
        if (advisorNames == null) {
            // 獲取當前BeanFactory中全部實現了Advisor接口的bean的名稱
            advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
                this.beanFactory, Advisor.class, true, false);
            this.cachedAdvisorBeanNames = advisorNames;
        }
    }
    if (advisorNames.length == 0) {
        return new LinkedList<>();
    }
 
    // 對獲取到的實現Advisor接口的bean的名稱進行遍歷
    List<Advisor> advisors = new LinkedList<>();
    for (String name : advisorNames) {
        // isEligibleBean()是提供的一個hook方法,用於子類對Advisor進行過濾,這裏默認返回值都是true
        if (isEligibleBean(name)) {
            // 若是當前bean還在建立過程當中,則略過,其建立完成以後會爲其判斷是否須要織入切面邏輯
            if (this.beanFactory.isCurrentlyInCreation(name)) {
                if (logger.isDebugEnabled()) {
                    logger.debug("Skipping currently created advisor '" + name + "'");
                }
            } else {
                try {
                    // 將當前bean添加到結果中
                    advisors.add(this.beanFactory.getBean(name, Advisor.class));
                } catch (BeanCreationException ex) {
                    // 對獲取過程當中產生的異常進行封裝
                    Throwable rootCause = ex.getMostSpecificCause();
                    if (rootCause instanceof BeanCurrentlyInCreationException) {
                        BeanCreationException bce = (BeanCreationException) rootCause;
                        String bceBeanName = bce.getBeanName();
                        if (bceBeanName != null && 
                            this.beanFactory.isCurrentlyInCreation(bceBeanName)) {
                            if (logger.isDebugEnabled()) {
                                logger.debug("Skipping advisor '" + name + 
                                    "' with dependency on currently created bean: " 
                                    + ex.getMessage());
                            }
                            continue;
                        }
                    }
                    throw ex;
                }
            }
        }
    }
    return advisors;
}

 

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

@Override
	public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
		//從 aspectMetadata 中獲取 Aspect()標註的類 class對象
		Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
		//獲取Aspect()標註的類名
		String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName();
		validate(aspectClass);

		// We need to wrap the MetadataAwareAspectInstanceFactory with a decorator
		// so that it will only instantiate once.
		MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory =
				new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory);

		List<Advisor> advisors = new LinkedList<>();
		//遍歷該類全部方法,根據方法判斷是否能獲取到對應 pointCut,若是有,則生成 advisor 對象
		for (Method method : getAdvisorMethods(aspectClass)) {
                        //這裏繼續看下面的解析
			Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName);
			if (advisor != null) {
				advisors.add(advisor);
			}
		}

		// If it's a per target aspect, emit the dummy instantiating aspect.
		if (!advisors.isEmpty() && lazySingletonAspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
			Advisor instantiationAdvisor = new SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory);
			advisors.add(0, instantiationAdvisor);
		}

		// Find introduction fields.
		//獲取 @DeclareParents 註解修飾的屬性(並不經常使用)
		for (Field field : aspectClass.getDeclaredFields()) {
			Advisor advisor = getDeclareParentsAdvisor(field);
			if (advisor != null) {
				advisors.add(advisor);
			}
		}

		return advisors;
	}

 繼續來看getAdvisor方法:

@Override
	@Nullable
	public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory,
			int declarationOrderInAspect, String aspectName) {

		validate(aspectInstanceFactory.getAspectMetadata().getAspectClass());
		//根據候選方法名,來獲取對應的 pointCut
		AspectJExpressionPointcut expressionPointcut = getPointcut(
				candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass());
		if (expressionPointcut == null) {
			return null;
		}
		//若是能獲取到 pointCut,則將切點表達式 expressionPointcut、當前
		對象ReflectiveAspectJAdvisorFactory、 方法名等包裝成 advisor 對象
		return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod,
				this, aspectInstanceFactory, declarationOrderInAspect, aspectName);
	}

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

public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut,
			MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {
		//......
		//根據註解類型,匹配對應的通知類型
		switch (aspectJAnnotation.getAnnotationType()) {
			//前置通知
			case AtBefore:
				springAdvice = new AspectJMethodBeforeAdvice(
						candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
				break;
			//最終通知
			case AtAfter:
				springAdvice = new AspectJAfterAdvice(
						candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
				break;
			//後置通知
			case AtAfterReturning:
				springAdvice = new AspectJAfterReturningAdvice(
						candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
				AfterReturning afterReturningAnnotation = (AfterReturning) aspectJAnnotation.getAnnotation();
				if (StringUtils.hasText(afterReturningAnnotation.returning())) {
					springAdvice.setReturningName(afterReturningAnnotation.returning());
				}
				break;
			//異常通知
			case AtAfterThrowing:
				springAdvice = new AspectJAfterThrowingAdvice(
						candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
				AfterThrowing afterThrowingAnnotation = (AfterThrowing) aspectJAnnotation.getAnnotation();
				if (StringUtils.hasText(afterThrowingAnnotation.throwing())) {
					springAdvice.setThrowingName(afterThrowingAnnotation.throwing());
				}
				break;
			//環繞通知
			case AtAround:
				springAdvice = new AspectJAroundAdvice(
						candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
				break;
			//切面
			case AtPointcut:
				if (logger.isDebugEnabled()) {
					logger.debug("Processing pointcut '" + candidateAdviceMethod.getName() + "'");
				}
				return null;
			default:
				throw new UnsupportedOperationException(
						"Unsupported advice type on method: " + candidateAdviceMethod);
		}

		//......
	}

 

能夠看到,根據@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方法中

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);
    //檢查proxyTargeClass設置以及preserveTargetClass屬性  
    //決定對於給定的bean是否應該使用targetClass而不是他的接口代理
    if (!proxyFactory.isProxyTargetClass()) {
        if (shouldProxyTargetClass(beanClass, beanName)) {
            proxyFactory.setProxyTargetClass(true);
        }
        else {
            //用來添加代理接口
            evaluateProxyInterfaces(beanClass, proxyFactory);
        }
    }

    Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
    //加入加強器
    proxyFactory.addAdvisors(advisors);
    //設置要代理的類
    proxyFactory.setTargetSource(targetSource);
    //定製代理
    customizeProxyFactory(proxyFactory);
    //用來控制代理工廠被設置後是否還容許修改通知,缺省值爲false
    proxyFactory.setFrozen(this.freezeProxy);
    if (advisorsPreFiltered()) {
        proxyFactory.setPreFiltered(true);
    }

    return proxyFactory.getProxy(getProxyClassLoader());
}

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

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

protected void evaluateProxyInterfaces(Class<?> beanClass, ProxyFactory proxyFactory) {
        Class<?>[] targetInterfaces = ClassUtils.getAllInterfacesForClass(beanClass, getProxyClassLoader());
        boolean hasReasonableProxyInterface = false;
        for (Class<?> ifc : targetInterfaces) {
            if (!isConfigurationCallbackInterface(ifc) && !isInternalLanguageInterface(ifc) &&
                    ifc.getMethods().length > 0) {
                hasReasonableProxyInterface = true;
                break;
            }
        }
        if (hasReasonableProxyInterface) {
            // Must allow for introductions; can't just set interfaces to the target's interfaces only.
            for (Class<?> ifc : targetInterfaces) {
                proxyFactory.addInterface(ifc);
            }
        }
        else {
            proxyFactory.setProxyTargetClass(true);
        }
    }

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

在createProxy方法最後返回的getProxy方法中能夠看到

public Object getProxy(@Nullable ClassLoader classLoader) {
        return createAopProxy().getProxy(classLoader);
    }

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

@Override
	public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
		if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
			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.");
			}
			if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
				return new JdkDynamicAopProxy(config);
			}
			return new ObjenesisCglibAopProxy(config);
		}
		else {
			return new JdkDynamicAopProxy(config);
		}
	}

 

六: 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的擴展接口中來建立代理類。