1. 程式人生 > >(八)Spring核心框架

(八)Spring核心框架



一、AOP的體系結構

如下圖所示:(引自AOP聯盟)

層次3語言和開發環境:基礎是指待增加物件或者目標物件;切面通常包括對於基礎的增加應用;配置是指AOP體系中提供的配置環境或者編織配置,通過該配置AOP將基礎和切面結合起來,從而完成切面對目標物件的編織實現。

層次2面向方面系統:配置模型,邏輯配置和AOP模型是為上策的語言和開發環境提供支援的,主要功能是將需要增強的目標物件、切面和配置使用AOPAPI轉換、抽象、封裝成面向方面中的邏輯模型。

層次1底層編織實現模組:主要是將面向方面系統抽象封裝的AOP模型編織進待增強的目標物件的實現技術。

二、AOP的原理

AOP 代理其實是由 AOP 框架動態生成的一個物件,該物件可作為目標物件使用。AOP 代理包含了目標物件的全部方法,但 AOP 代理中的方法與目標物件的方法存在差異:AOP 方法在特定切入點添加了增強處理,並回調了目標物件的方法。

Spring 的 AOP 代理由 Spring 的 IoC 容器負責生成、管理,其依賴關係也由 IoC 容器負責管理。因此,AOP 代理可以直接使用容器中的其他 Bean 例項作為目標,這種關係可由 IoC 容器的依賴注入提供。

縱觀 AOP 程式設計,其中需要程式設計師參與的只有 3 個部分:
定義普通業務元件。
定義切入點,一個切入點可能橫切多個業務元件。
定義增強處理,增強處理就是在 AOP 框架為普通業務元件織入的處理動作。

上面 3 個部分的第一個部分是最平常不過的事情,無須額外說明。那麼進行 AOP 程式設計的關鍵就是定義切入點和定義增強處理。一旦定義了合適的切入點和增強處理,AOP 框架將會自動生成 AOP 代理,而 AOP 代理的方法大致有如下公式:

代理物件的方法 = 增強處理 + 被代理物件的方法

在上面這個業務定義中,不難發現 Spring AOP 的實現原理其實很簡單:AOP 框架負責動態地生成 AOP 代理類,這個代理類的方法則由 Advice 和回撥目標物件的方法所組成。

簡而言之:AOP 原理的奧妙就在於動態地生成了代理類。下面介紹使用 CGLIB 來生成代理類。

CGLIB 來生成代理類

CGLIB(Code Generation Library),簡單來說,就是一個程式碼生成類庫。它可以在執行時候動態是生成某個類的子類。

此處使用前面定義的 Chinese 類,現在改為直接使用 CGLIB 來生成代理,這個代理類同樣可以實現 Spring AOP 代理所達到的效果。

下面先為 CGLIB 提供一個攔截器實現類:

public class AroundAdvice implements MethodInterceptor {
	public Object intercept(Object target, Method method, Object[] args,
			MethodProxy proxy) throws java.lang.Throwable {
		System.out.println("執行目標方法之前,模擬開始事務 ...");
		// 執行目標方法,並儲存目標方法執行後的返回值
		Object rvt = proxy.invokeSuper(target, new String[] { "被改變的引數" });
		System.out.println("執行目標方法之後,模擬結束事務 ...");
		return rvt + " 新增的內容";
	}
}

上面這個 AroundAdvice.java 的作用就像前面介紹的 Around Advice,它可以在呼叫目標方法之前、呼叫目標方法之後織入增強處理。

接下來程式提供一個 ChineseProxyFactory 類,這個 ChineseProxyFactory 類會通過 CGLIB 來為 Chinese 生成代理類:

public class ChineseProxyFactory {
	public static Chinese getAuthInstance() {
		Enhancer en = new Enhancer();
		// 設定要代理的目標類
		en.setSuperclass(Chinese.class);
		// 設定要代理的攔截器
		en.setCallback(new AroundAdvice());
		// 生成代理類的例項
		return (Chinese) en.create();
	}
}

上面粗體字程式碼就是使用 CGLIB 的 Enhancer 生成代理物件的關鍵程式碼,此時的 Enhancer 將以 Chinese 類作為目標類,以 AroundAdvice 物件作為“Advice”,程式將會生成一個 Chinese 的子類,這個子類就是 CGLIB 生成代理類,它可作為 Chinese 物件使用,但它增強了 Chinese 類的方法。

CGLIB 生成的代理完全可以作為 Chinese 物件來使用,而且 CGLIB 代理物件的 sayHello()、eat() 兩個方法已經增加了事務控制(只是模擬),這個 CGLIB 代理其實就是 Spring AOP 所生成的 AOP 代理。

這就是 Spring AOP 的根本所在:Spring AOP 就是通過 CGLIB 來動態地生成代理物件,這個代理物件就是所謂的 AOP 代理,而 AOP 代理的方法則通過在目標物件的切入點動態地織入增強處理,從而完成了對目標方法的增強。

三、Spring AOP的底層實現常用類

分析Spring AOP的底層實現首先要從ProxyConfig類開始,ProxyConfig是所有產生Spring AOP代理物件的基類,它是一個數據類,主要為其AOP代理物件工廠實現類提供配置屬性。根據ProxyConfig的繼承體系分析建立AOP代理常用類的作用:

(1)AdvisedSupport是ProxyConfig的子類,它封裝了AOP中對通知(Advice)和通知器(Advisor)的相關操作,這些操作對於不同的AOP的代理物件的生成都是一樣的,但對於具體的AOP代理物件的建立,AdvisedSupport把它交給子類去實現。

(2)ProxyCreatorSupport是AdvisedSupport的子類,它是其子類建立AOP代理物件的一個輔助類,提供不同AOP代理物件生成的通用操作,具體的AOP代理物件生成,由ProxyCreatorSupport的子類完成。

(3)建立AOP代理物件的類:

ProxyCreatorSupport有3個子類,分別建立不同的AOP代理物件,具體如下:

a.AspectJProxyFactory:主要用於建立AspectJ的AOP應用,起到整合Spring和AspectJ的作用。

b.ProxyFactory:建立程式設計式的Spring AOP應用。

c.ProxyFactoryBean:建立宣告式的Spring AOP應用。

四、Spring AOP代理原始碼解析

1、宣告式Spring AOP代理工廠物件ProxyFactoryBean:

我們以ProxyFactoryBean為例,分析Spring AOP的實現原理,ProxyFactoryBean是Spring中一個非常靈活的建立AOP應用的底層方法,封裝了AOP的主要功能。

一個簡單的AOP代理工廠物件的配置如下:

<!--配置通知器,通知器的實現定義了需要對目標物件進行的增強行為-->
<bean id=”testAdvisor” class=”com.test.TestAdvisor”/>
<!--配置AOP代理,封裝AOP功能的主要類-->
<bean id=”testAOP” class=”org.springframework.aop.ProxyFactoryBean”>
	<!--AOP代理介面-->
	<property name=”proxyInterfaces”>
		<value>com.test.TestProxyInterface</value>
	</property>
	<!--需要使用AOP切面增強的物件-->
	<property name=”target”>
		<bean class=”com.test.TestTarget”/>
	</property>
	<!--代理攔截器,配置通知器的名稱,即通知器在AOP代理的配置下通過使用代理物件的攔截機制發揮作用-->
	<property name=”interceptorNames”>
		<list>
			<value>testAdvisor</value>
		</list>
	</property>
</bean>

2、ProxyFactoryBean生成AOP Proxy代理物件:

從上面的ProxyFactoryBean的簡單配置例子我們可以看出,ProxyFactoryBean是用來配置目標物件和切面行為Advice的,ProxyFactoryBean通過其配置的攔截器名稱interceptorNames即通知器Advisor將切面行為Advice應用到目標物件中。

在ProxyFactoryBean中,需要為待增強目標物件目標物件生成Proxy代理物件,從而為AOP切面的編織提供基礎,下面通過原始碼分析ProxyFactoryBean的生成AOPProxy代理物件的實現過程:

(1)ProxyFactoryBean產生代理物件的主要原始碼:

public class ProxyFactoryBean extends ProxyCreatorSupport
		implements FactoryBean<Object>, BeanClassLoaderAware, BeanFactoryAware {
//標註通知器器為全域性通用通知器
public static final String GLOBAL_SUFFIX = "*";
//標誌通知器鏈是否已經完成初始化
private boolean advisorChainInitialized = false;
//單態模式物件
private Object singletonInstance;
……
//ProxyFactoryBean建立AOPProxy代理的入口方法
public Object getObject() throws BeansException {
		//初始化通知器鏈
		initializeAdvisorChain();
		//如果目標物件是單態模式
		if (isSingleton()) {
			//呼叫獲取單態模式物件的方法產生AOPProxy代理
			return getSingletonInstance();
		}
		//如果目標物件是原型模式
		else {
			if (this.targetName == null) {
				logger.warn("Using non-singleton proxies with singleton targets is often undesirable. " +
						"Enable prototype proxies by setting the 'targetName' property.");
			}
			//呼叫原型模式物件方法每次建立一個新的AOPProxy代理物件
			return newPrototypeInstance();
		}
	}
//初始化通知器鏈
private synchronized void initializeAdvisorChain() throws AopConfigException, BeansException {
	//如果通知器鏈已經被初始化,則直接返回,即通知器鏈只在第一次獲取代理物件時產生
		if (this.advisorChainInitialized) {
			return;
		}
		//如果ProxyFactoryBean中配置的聯結器列名名稱不為空
		if (!ObjectUtils.isEmpty(this.interceptorNames)) {
			//如果沒有Bean工廠(容器)
			if (this.beanFactory == null) {
				throw new IllegalStateException("No BeanFactory available anymore (probably due to serialization) " +
						"- cannot resolve interceptor names " + Arrays.asList(this.interceptorNames));
			}
			//全域性通知器不能是通知器鏈中最後一個,除非顯式使用屬性指定了目標
			if (this.interceptorNames[this.interceptorNames.length - 1].endsWith(GLOBAL_SUFFIX) &&
					this.targetName == null && this.targetSource == EMPTY_TARGET_SOURCE) {
				throw new AopConfigException("Target required after globals");
			}
			//遍歷通知器鏈,向容器新增通知器
			for (String name : this.interceptorNames) {
				if (logger.isTraceEnabled()) {
					logger.trace("Configuring advisor or advice '" + name + "'");
				}
				//如果通知器是全域性的
				if (name.endsWith(GLOBAL_SUFFIX)) {
					if (!(this.beanFactory instanceof ListableBeanFactory)) {
						throw new AopConfigException(
								"Can only use global advisors or interceptors with a ListableBeanFactory");
					}
					//向容器中新增全域性通知器
					addGlobalAdvisor((ListableBeanFactory) this.beanFactory,
							name.substring(0, name.length() - GLOBAL_SUFFIX.length()));
				}
				//如果通知器不是全域性的
				else {
					Object advice;
					//如果通知器是單態模式
					if (this.singleton || this.beanFactory.isSingleton(name)) {
						//從容器獲取單態模式的通知或者通知器
						advice = this.beanFactory.getBean(name);
					}
					//如果通知器是原型模式
					else {
						//建立一個新的通知或者通知器物件
						advice = new PrototypePlaceholderAdvisor(name);
					}
					//新增通知器
					addAdvisorOnChainCreation(advice, name);
				}
			}
		}
		//設定通知器鏈已初始化標識
		this.advisorChainInitialized = true;
	}
//獲取一個單態模式的AOPProxy代理物件
private synchronized Object getSingletonInstance() {
		//如果單態模式的代理物件還未被建立
		if (this.singletonInstance == null) {
			//獲取代理的目標源
			this.targetSource = freshTargetSource();
			//如果ProxyFactoryBean設定了自動探測介面屬性,並且沒有配置代理接
			//且不是目標物件的直接代理類
			if (this.autodetectInterfaces && getProxiedInterfaces().length == 0 && !isProxyTargetClass()) {
				//獲取代理物件的目標類
				Class targetClass = getTargetClass();
				if (targetClass == null) {
					throw new FactoryBeanNotInitializedException("Cannot determine target class for proxy");
				}
			//設定代理物件的介面	setInterfaces(ClassUtils.getAllInterfacesForClass(targetClass, this.proxyClassLoader));
			}
	//初始化共享的單態模式物件					 super.setFrozen(this.freezeProxy);
	//呼叫ProxyFactory生成代理AOPProxy物件
			this.singletonInstance = getProxy(createAopProxy());
		}
		return this.singletonInstance;
	}
//獲取一個原型模式的代理物件
private synchronized Object newPrototypeInstance() {
		if (logger.isTraceEnabled()) {
			logger.trace("Creating copy of prototype ProxyFactoryBean config: " + this);
		}
		//根據當前的AOPProxyFactory獲取一個建立代理的輔助類
		ProxyCreatorSupport copy = new ProxyCreatorSupport(getAopProxyFactory());
		//獲取一個重新整理的目標源
		TargetSource targetSource = freshTargetSource();
		//從當前物件中拷貝AOP的配置,為了保持原型模式物件的獨立性,每次建立代理
//物件時都需要拷貝AOP的配置,以保證原型模式AOPProxy代理物件的獨立性
		copy.copyConfigurationFrom(this, targetSource, freshAdvisorChain());
		if (this.autodetectInterfaces && getProxiedInterfaces().length == 0 && !isProxyTargetClass()) {
			//設定代理介面
			copy.setInterfaces(
	ClassUtils.getAllInterfacesForClass(targetSource.getTargetClass(), this.proxyClassLoader));
		}
		copy.setFrozen(this.freezeProxy);
		if (logger.isTraceEnabled()) {
			logger.trace("Using ProxyCreatorSupport copy: " + copy);
		}
		//呼叫ProxyFactory生成AOPProxy代理
		return getProxy(copy.createAopProxy());
	}
//使用createAopProxy方法返回的AOPProxy物件產生AOPProxy代理物件
protected Object getProxy(AopProxy aopProxy) {
		return aopProxy.getProxy(this.proxyClassLoader);
	}
……
}

通過原始碼分析,我們瞭解到AOPProxyFactory實現了FactoryBean介面,所以本身也是一個Spring的工廠Bean,AOP代理工廠的主要功能概況為:

a.初始化通知器鏈,將配置的通知器鏈新增到容器存放通知/通知器的集合中。

b.根據單態模式/原型模式,獲取AOPProxy產生AOPProxy代理物件。

(2)AOP建立輔助器(AOPCreatorSupport)獲取AOP Proxy代理物件:

AOP ProxyFactory的getSingletonInstance和newPrototypeInstance方法均通過呼叫AOPCreatorSupport的createAopProxy()方法獲取AOP Proxy,主要原始碼如下:

public class ProxyCreatorSupport extends AdvisedSupport {
//AOPProxy工廠
private AopProxyFactory aopProxyFactory;
//當第一個AOPProxy代理物件被建立時,設定為true
private boolean active = false;
public AopProxyFactory getAopProxyFactory() {
		return this.aopProxyFactory;
	}
//預設使用DefaultAopProxyFactory作用AOP代理工廠
public ProxyCreatorSupport() {
		this.aopProxyFactory = new DefaultAopProxyFactory();
	}
//建立AOPProxy代理的入口方法
protected final synchronized AopProxy createAopProxy() {
		if (!this.active) {
			activate();
		}
		//呼叫DefaultAopProxyFactory的建立AOPProxy代理的方法
		return getAopProxyFactory().createAopProxy(this);
	} 
//啟用AOP代理配置,向容器註冊代理回撥監聽器,第一次建立AOP代理時呼叫
private void activate() {
		this.active = true;
		for (AdvisedSupportListener listener : this.listeners) {
			listener.activated(this);
		}
	} 
……
}

通過對ProxyCreatorSupport的原始碼分析,我們知道真正建立AOPProxy代理物件的是DefaultAopProxyFactory類。

(3)DefaultAopProxyFactory建立AOP Proxy代理物件:

DefaultAopProxyFactory是AOP建立輔助器(AOPCreatorSupport)預設的AOP代理工廠,DefaultAopProxyFactory的createAopProxy方法實現了建立AOP代理的功能,原始碼如下:

public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {
//判斷CGLIB類庫是否在classpath中
private static final boolean cglibAvailable =
			ClassUtils.isPresent("net.sf.cglib.proxy.Enhancer", DefaultAopProxyFactory.class.getClassLoader());
//建立AOP代理物件
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
		//如果AOP使用顯式優化,或者配置了目標類,或者只使用Spring支援的代理介面
		if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
			//獲取AOP配置的目標類
			Class targetClass = config.getTargetClass();
			if (targetClass == null) {
				throw new AopConfigException("TargetSource cannot determine target class: " +
						"Either an interface or a target is required for proxy creation.");
			}
			//如果配置的AOP目標類是介面,則使用JDK動態代理機制來生成AOP代理
			if (targetClass.isInterface()) {
				return new JdkDynamicAopProxy(config);
			}
			//如果AOP配置的目標類不是介面,則使用CGLIB的方式來生成AOP代理
			if (!cglibAvailable) {
				throw new AopConfigException(
						"Cannot proxy target class because CGLIB2 is not available. " +
						"Add CGLIB to the class path or specify proxy interfaces.");
			}
			return CglibProxyFactory.createCglibProxy(config);
		}
		else {
			return new JdkDynamicAopProxy(config);
		}
	}
//判斷AOP是否只配置了SpringProxy代理介面或者沒有配置任何代理介面
	private boolean hasNoUserSuppliedProxyInterfaces(AdvisedSupport config) {
		//獲取AOP配置的所有AOP代理介面
		Class[] interfaces = config.getProxiedInterfaces();
		return (interfaces.length == 0 || (interfaces.length == 1 && SpringProxy.class.equals(interfaces[0])));
	}
}

通過對DefaultAopProxyFactory的原始碼分析,我們瞭解了Spring在建立AOP代理物件時,如果配置的目標類是介面,則使用JDK的動態代理機制來生成AOP代理,如果使用的不是介面,則使用CGLIB方式來生成AOP的動態代理。

3、JDK動態代理機制建立AOPProxy代理物件:

JDK的動態代理機制只能對介面起作用,即如果要對一個物件使用JDK動態代理方式生成代理物件時,該物件必須實現介面,Spring中通過JdkDynamicAopProxy類使用JDK動態代理機制生成AOPProxy代理物件,JdkDynamicAopProxy的主要原始碼如下:

final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable {
……
//JdkDynamicAopProxy的構造方法
	public JdkDynamicAopProxy(AdvisedSupport config) throws AopConfigException {
		Assert.notNull(config, "AdvisedSupport must not be null");
		//獲取AOPBeanFactory中配置的通知器鏈和目標源
		if (config.getAdvisors().length == 0 && config.getTargetSource() == AdvisedSupport.EMPTY_TARGET_SOURCE) {
			throw new AopConfigException("No advisors and no TargetSource specified");
		}
		//為當前物件設定AOP配置
		this.advised = config;
	}
	//獲取AOP代理物件的入口方法
	public Object getProxy() {
		return getProxy(ClassUtils.getDefaultClassLoader());
	}
	//建立AOP代理物件
	public Object getProxy(ClassLoader classLoader) {
		if (logger.isDebugEnabled()) {
			logger.debug("Creating JDK dynamic proxy: target source is " + this.advised.getTargetSource());
		}
		//獲取AOPBeanFactory中配置的代理介面
		Class[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised);
		//查詢代理目標的介面中是否定義equals()和hashCode()方法
		findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
		//使用JDK的動態代理機制建立AOP代理物件
		return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
	}
	//查詢給定類或介面中是否定義了equals()和hashCode()方法
	private void findDefinedEqualsAndHashCodeMethods(Class[] proxiedInterfaces) {
		//遍歷給定的類/介面陣列
		for (Class proxiedInterface : proxiedInterfaces) {
			//或者給定類/介面中所有宣告的方法
			Method[] methods = proxiedInterface.getDeclaredMethods();
			//遍歷類/介面中的宣告的方法
			for (Method method : methods) {
				//如果方法是equals()方法,則設定當前物件equalsDefined屬性
				if (AopUtils.isEqualsMethod(method)) {
					this.equalsDefined = true;
				}
//如果方法是hashCode()方法,則設定當前物件hashCodeDefined屬性
				if (AopUtils.isHashCodeMethod(method)) {
					this.hashCodeDefined = true;
				}
				if (this.equalsDefined && this.hashCodeDefined) {
					return;
				}
			}
		}
	}
//AOP代理物件的回撥方法
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		MethodInvocation invocation;
		Object oldProxy = null;
		boolean setProxyContext = false;
		//獲取通知的目標源
		TargetSource targetSource = this.advised.targetSource;
		Class targetClass = null;
		Object target = null;
		try {
			//如果代理目標物件的介面中沒有定義equals()方法,且當前呼叫的方法
//是equals()方法,即目標物件沒有自己實現equals()方法
			if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
				return equals(args[0]);
			}
			//如果代理目標物件的介面中沒有定義hashCode()方法,且當前呼叫的方法
//是hashCode()方法,即目標物件沒有自己實現hashCode()方法
			if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
				return hashCode();
			}
			//如果AOP配置了通知,使用反射機制呼叫通知的同名方法
			if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&				method.getDeclaringClass().isAssignableFrom(Advised.class)) {
				return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
			}
			Object retVal;
		//如果當前通知暴露了代理,則將當前代理使用currentProxy()方法變為可用代理
			if (this.advised.exposeProxy) {
				oldProxy = AopContext.setCurrentProxy(proxy);
				setProxyContext = true;
			}
			//獲取目標物件
			target = targetSource.getTarget();
			if (target != null) {
				targetClass = target.getClass();
			}
			//獲取目標物件方法配置的攔截器(通知器)鏈
			List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
			//如果沒有配置任何通知
			if (chain.isEmpty()) {
				//沒有配置通知,使用反射直接呼叫目標物件的方法,並獲取方法返回值
				retVal = AopUtils.invokeJoinpointUsingReflection(target, method, args);
			}
			//如果配置了通知
			else {
			//為目標物件建立方法回撥物件,需要在呼叫通知之後才呼叫目標物件的方法
				invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
				//呼叫通知鏈,沿著通知器鏈呼叫所有配置的通知
				retVal = invocation.proceed();
			}
			//如果方法有返回值,則將代理物件最為方法返回
			if (retVal != null && retVal == target && method.getReturnType().isInstance(proxy) &&
					!RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
				retVal = proxy;
			}
			return retVal;
		}
		finally {
			if (target != null && !targetSource.isStatic()) {
				//釋放目標物件
				targetSource.releaseTarget(target);
			}
			if (setProxyContext) {
				//儲存代理物件
				AopContext.setCurrentProxy(oldProxy);
			}
		}
	}
……
}

通過上述原始碼分析,我們看到JdkDynamicAopProxy本身實現了InvocationHandler介面和invoke()方法,JDK的動態代理機制的工作原理是:當呼叫目標物件的方法時,不是直接呼叫目標物件,而是首先生成一個目標物件的動態代理物件,觸發代理物件的invoke()方法,代理的invoke()方法才會真正呼叫目標物件的方法。Spring AOP的實現原理是在代理物件invoke()方法呼叫目標物件的方法時,呼叫配置的通知。

4、CglibProxyFactory建立AOP Proxy代理:

JDK的動態代理只能針對介面生成代理物件,對於沒有實現介面的目標物件,必須通過第3方的CGLIB來生成代理物件,CglibProxyFactory建立AOPProxy代理的主要原始碼如下:

//通過CGLIB方式建立AOP代理物件
public Object getProxy(ClassLoader classLoader) {
		if (logger.isDebugEnabled()) {
			logger.debug("Creating CGLIB2 proxy: target source is " + this.advised.getTargetSource());
		}
		try {
			//從代理建立輔助類中獲取在IoC容器中配置的目標物件
			Class rootClass = this.advised.getTargetClass();
			Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");
			//將目標物件本身做為自己的基類
			Class proxySuperClass = rootClass;
			//檢查獲取到的目標類是否是CGLIB產生的
			if (AopUtils.isCglibProxyClass(rootClass)) {
				//如果目標類是有CGLIB產生的,獲取目標類的基類
				proxySuperClass = rootClass.getSuperclass();
				//獲取目標類的介面
				Class[] additionalInterfaces = rootClass.getInterfaces();
				//將目標類的介面新增到容器AOP代理建立輔助類的配置中
				for (Class additionalInterface : additionalInterfaces) {
					this.advised.addInterface(additionalInterface);
				}
			}
			//校驗代理基類
			validateClassIfNecessary(proxySuperClass);
			//配置CGLIB的Enhancer類,Enhancer是CGLIB中的主要操作類
			Enhancer enhancer = createEnhancer();
			if (classLoader != null) {
				enhancer.setClassLoader(classLoader);
				if (classLoader instanceof SmartClassLoader &&
						((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
					enhancer.setUseCache(false);
				}
			}
			//設定enhancer的基類
			enhancer.setSuperclass(proxySuperClass);
			enhancer.setStrategy(new UndeclaredThrowableStrategy(UndeclaredThrowableException.class));
	//設定enhancer的介面	enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
			enhancer.setInterceptDuringConstruction(false);
			//設定enhancer的回撥方法
			Callback[] callbacks = getCallbacks(rootClass);
			enhancer.setCallbacks(callbacks);
			//將通知器中配置作為enhancer的方法過濾
			enhancer.setCallbackFilter(new ProxyCallbackFilter(
					this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
			Class[] types = new Class[callbacks.length];
			for (int x = 0; x < types.length; x++) {
				types[x] = callbacks[x].getClass();
			}
			//設定enhancer的回撥型別
			enhancer.setCallbackTypes(types);
			//建立代理物件
			Object proxy;
			if (this.constructorArgs != null) {
				proxy = enhancer.create(this.constructorArgTypes, this.constructorArgs);
			}
			else {
				proxy = enhancer.create();
			}
			return proxy;
		}
		catch (CodeGenerationException ex) {
			throw new AopConfigException("Could not generate CGLIB subclass of class [" +
					this.advised.getTargetClass() + "]: " +
					"Common causes of this problem include using a final class or a non-visible class",
					ex);
		}
		catch (IllegalArgumentException ex) {
			throw new AopConfigException("Could not generate CGLIB subclass of class [" +
					this.advised.getTargetClass() + "]: " +
					"Common causes of this problem include using a final class or a non-visible class",
					ex);
		}
		catch (Exception ex) {
			// TargetSource.getTarget() failed
			throw new AopConfigException("Unexpected AOP exception", ex);
		}
	}
//獲取給定類的回撥通知
 private Callback[] getCallbacks(Class rootClass) throws Exception {
		//優化引數
		boolean exposeProxy = this.advised.isExposeProxy();
		boolean isFrozen = this.advised.isFrozen();
		boolean isStatic = this.advised.getTargetSource().isStatic();
		//根據AOP配置建立一個動態通知攔截器,CGLIB建立的動態代理會自動呼叫
		//DynamicAdvisedInterceptor類的intercept方法對目標物件進行攔截處理
		Callback aopInterceptor = new DynamicAdvisedInterceptor(this.advised);
		Callback targetInterceptor;
		//根據是否暴露代理,建立直接應用目標的通知
		if (exposeProxy) {
			targetInterceptor = isStatic ?
					new StaticUnadvisedExposedInterceptor(this.advised.getTargetSource().getTarget()) :
					new DynamicUnadvisedExposedInterceptor(this.advised.getTargetSource());
		}
		else {
			targetInterceptor = isStatic ?
					new StaticUnadvisedInterceptor(this.advised.getTargetSource().getTarget()) :
					new DynamicUnadvisedInterceptor(this.advised.getTargetSource());
		}
		// 建立目標分發器
		Callback targetDispatcher = isStatic ?
				new StaticDispatcher(this.advised.getTargetSource().getTarget()) : new SerializableNoOp();
		Callback[] mainCallbacks = new Callback[]{
			aopInterceptor, //普通通知
			targetInterceptor, // 如果優化則不考慮配置的通知
			new SerializableNoOp(), //沒有被覆蓋的方法
			targetDispatcher, this.advisedDispatcher,
			new EqualsInterceptor(this.advised),
			new HashCodeInterceptor(this.advised)
		};
		Callback[] callbacks;
		//如果目標是靜態的,並且通知鏈被凍結,則使用優化AOP呼叫,直接對方法使用
//固定的通知鏈
		if (isStatic && isFrozen) {
			Method[] methods = rootClass.getMethods();
			Callback[] fixedCallbacks = new Callback[methods.length];
			this.fixedInterceptorMap = new HashMap<String, Integer>(methods.length);
			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);
			}
			//將固定回撥和主要回調拷貝到回撥陣列中
			callbacks = new Callback[mainCallbacks.length + fixedCallbacks.length];
			System.arraycopy(mainCallbacks, 0, callbacks, 0, mainCallbacks.length);
			System.arraycopy(fixedCallbacks, 0, callbacks, mainCallbacks.length, fixedCallbacks.length);
			this.fixedInterceptorOffset = mainCallbacks.length;
		}
		//如果目標不是靜態的,或者通知鏈不被凍結,則使用AOP主要的通知
		else {
			callbacks = mainCallbacks;
		}
		return callbacks;
	}

通過上面對CGLIB建立代理和獲取回答通知的原始碼分析,我們瞭解到CGLIB在獲取代理的通知時,會建立DynamicAdvisedInterceptor類,當應用呼叫目標物件的方法時,不是直接呼叫目標物件,而是通過CGLIB建立的代理物件來呼叫目標物件,在呼叫目標物件的方法時,觸發DynamicAdvisedInterceptor的intercept回撥方法對目標物件進行處理,CGLIB回撥攔截器鏈的原始碼如下:

//CGLIB回撥AOP攔截器鏈
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
			Object oldProxy = null;
			boolean setProxyContext = false;
			Class targetClass = null;
			Object target = null;
			try {
				//如果通知器暴露了代理
				if (this.advised.exposeProxy) {
					//設定給定的代理物件為要被攔截的代理							                 oldProxy = AopContext.setCurrentProxy(proxy);
					setProxyContext = true;
				}
				//獲取目標物件
				target = getTarget();
				if (target != null) {
					targetClass = target.getClass();
				}
				//獲取AOP配置的通知
				List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
				Object retVal;
				//如果沒有配置通知
				if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
					//直接呼叫目標物件的方法
					retVal = methodProxy.invoke(target, args);
				}
				//如果配置了通知
				else {
					//通過CglibMethodInvocation來啟動配置的通知
					retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
				}
				//獲取目標物件物件方法的回撥結果,如果有必要則封裝為代理
				retVal = massageReturnTypeIfNecessary(proxy, target, method, retVal);
				return retVal;
			}
			finally {
				if (target != null) {
					releaseTarget(target);
				}
				if (setProxyContext) {
					//儲存被回撥的代理
					AopContext.setCurrentProxy(oldProxy);
				}
			}
		}

5、目標物件方法的呼叫:

(1)JdkDynamicAopProxy直接呼叫目標物件方法:

JdkDynamicAopProxy中是通過AopUtils.invokeJoinpointUsingReflection方法來直接呼叫目標物件的方法,原始碼如下:

//通過反射機制直接呼叫目標物件方法
public static Object invokeJoinpointUsingReflection(Object target, Method method, Object[] args)
			throws Throwable {
		try {
//通過反射使給定的方法可以訪問,主要是對protected和private方法使用,//取消嚴格訪問控制權限的限制
			ReflectionUtils.makeAccessible(method);
			//使用反射機制呼叫目標物件的方法
			return method.invoke(target, args);
		}
		catch (InvocationTargetException ex) {
			throw ex.getTargetException();
		}
		catch (IllegalArgumentException ex) {
			throw new AopInvocationException("AOP configuration seems to be invalid: tried calling method [" +
					method + "] on target [" + target + "]", ex);
		}
		catch (IllegalAccessException ex) {
			throw new AopInvocationException("Could not access method [" + method + "]", ex);
		}
	}

(2)Cglib2AopProxy直接呼叫目標物件方法:

Cglib2AopProxy是通過methodProxy.invoke來直接呼叫目標物件的方法,主要原始碼如下:

retVal = methodProxy.invoke(target, args);