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的實現流程機制。