1. 程式人生 > >Spring AOP的實現:攔截器鏈的生成以及Advice通知的實現

Spring AOP的實現:攔截器鏈的生成以及Advice通知的實現

攔截器鏈的獲取生成

上一次我說到了攔截器鏈的獲取,攔截器鏈的獲取以及生成是從一個DefaultAdvisorChainFactory類中得到的。我們來看一下具體的實現程式碼

public List<Object> getInterceptorsAndDynamicInterceptionAdvice(
			Advised config, Method method, Class<?> targetClass)

首先宣告一條攔截器鏈,作為最後的返回的結果。

List<Object> interceptorList = new ArrayList<Object>(config.getAdvisors().length);

這個方法的入參我們可以看到有一個config,這個config就是之前的ProxyFactoryBean物件。這個方法從這個裡面獲取到通知器(Advistor)。攔截器鏈是通過AdvisorAdapterRegistry來加入的。這個AdvisorAdapterRegistry對advice織入起了很大的作用。

MethodInterceptor[] interceptors = registry.getInterceptors(advisor);

通過一個通知器獲得一條攔截器鏈,然後將這個攔截器鏈加入到之前宣告的interceptorList 中。

這裡的advistor通知器是從AdvisorSupport中取得的。

這個方法的實現可以從我們之前的initializeAdvisorChain方法去尋找。

之前的interceptorNames就在我們的之前的xml檔案中配置了。通過獲取interceptorNames中的name可以獲得

我們需要的advisor,是通過getBean()方法來獲取

advice = this.beanFactory.getBean(name);

advisor通知器的取得是由IoC容器完成的,但是在ProxyFactoryBean中是如何獲得,然後通過回撥IoC容器的getBean方法來得到需要的通知器呢?這涉及到IoC的實現原理,我們可以檢視AbstractAutowireCapableBeanFactory,可以看到一個對Bean進行初始化的initializeBean方法。在這個Bean的初始化過程中,對IoC容器在Bean的回撥中進行了設定,如果這個Bean實現了BeanFactoryAware定義的介面方法就可以呼叫IoC容器。

Advice通知的實現

之前的程式碼分析可以看到Aop代理物件和攔截器鏈都已經建立了起來,但是具體對於目標物件的目標方法還沒有建立起來。

從程式碼的實現中,我們可以看到

AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();

MethodInterceptor[] interceptors = registry.getInterceptors(advisor);

    在GlobalAdvisorAdapterRegistry中隱藏著不少AOP實現的重要細節,它的獲取我們可以來看一下

private static AdvisorAdapterRegistry instance = new DefaultAdvisorAdapterRegistry();

這個DefaultAdvistorAdapterRegistry中設定了一系列的adapter介面卡,正是這些adapater介面卡的實現,為Spring AOP的advice提供編織能力。我們來看一下實現的程式碼。

這個連結串列配置的是一系列的介面卡

private final List<AdvisorAdapter> adapters = new ArrayList<AdvisorAdapter>(3);

 在構造方法裡面我們可以看到這個adapters裡面裝入的是三個介面卡型別

public DefaultAdvisorAdapterRegistry() {
		registerAdvisorAdapter(new MethodBeforeAdviceAdapter());
		registerAdvisorAdapter(new AfterReturningAdviceAdapter());
		registerAdvisorAdapter(new ThrowsAdviceAdapter());
	}
public void registerAdvisorAdapter(AdvisorAdapter adapter) {
		this.adapters.add(adapter);
	}

這個是在DefaultAdvisorChainFactory中啟動的getInteceptors方法

public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {
		List<MethodInterceptor> interceptors = new ArrayList<MethodInterceptor>(3);
		Advice advice = advisor.getAdvice();
		if (advice instanceof MethodInterceptor) {
			interceptors.add((MethodInterceptor) advice);
		}
		for (AdvisorAdapter adapter : this.adapters) {
			if (adapter.supportsAdvice(advice)) {
				interceptors.add(adapter.getInterceptor(advisor));
			}
		}
		if (interceptors.isEmpty()) {
			throw new UnknownAdviceTypeException(advisor.getAdvice());
		}
		return interceptors.toArray(new MethodInterceptor[interceptors.size()]);
	}

 

我們可以看到如何對通知器進行適配,使用已經配置好的介面卡Adapter: MethodBeforeAdviceAdapter,

AfterReturningAdviceAdapter以及ThrowsAdviceAdapter,然後從對應的adapeter中取出封裝好的AOP編織功能的攔截器。

我們來看看這三個攔截器是如何實現對方法的增強的。

@Override
	public boolean supportsAdvice(Advice advice) {
		return (advice instanceof MethodBeforeAdvice);
	}

	@Override
	public MethodInterceptor getInterceptor(Advisor advisor) {
		MethodBeforeAdvice advice = (MethodBeforeAdvice) advisor.getAdvice();
		return new MethodBeforeAdviceInterceptor(advice);
	}

我們進入MethodBeforeAdviceInterceptor類中來看一下具體是怎麼實現的。

@Override
	public Object invoke(MethodInvocation mi) throws Throwable {
		this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis() );
		return mi.proceed();
	}

這個方法就是攔截器的回撥方法,會在代理方法被呼叫的時候觸發回撥。

同理我們可以在書上看到其他兩個方法的實現原理和這個是類似的。

至此Spring AOP的實現原理就已經結束了。只能說書上講述的原理流程還是比較清楚的。但是作為初學者的我來說即使看了不止一遍也還是有些不太理解。所以下一次我會把整個Spring AOP的流程再具體講一下。作為一個總結和收尾。然後開始Spring MVC的實現流程機制。