拦截器链的获取生成
上一次我说到了拦截器链的获取,拦截器链的获取以及生成是从一个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的实现流程机制。