spring AOP源码分析之拦截器
我们都知道在springAOP中产生代理对象的方式有jdk和cglib的方式生成,无论那种方式,AOP的拦截的处理都是通过ReflectiveMethodInvocation中的proceed方法
其方法的源码如下:
publicObjectproceed()
throwsThrowable
{
//如果拦截器迭代完毕,这里开始调用目标方法
if(currentInterceptorIndex==interceptorsAndDynamicMethodMatchers.size()-1)
returninvokeJoinpoint();
//从拦截器的集合中获取拦截器
ObjectinterceptorOrInterceptionAdvice=interceptorsAndDynamicMethodMatchers.get(++currentInterceptorIndex);
//判断如果是该类型的
if(interceptorOrInterceptionAdviceinstanceofInterceptorAndDynamicMethodMatcher)
{
InterceptorAndDynamicMethodMatcherdm=(InterceptorAndDynamicMethodMatcher)interceptorOrInterceptionAdvice;
//那么对方法进行匹配
if(dm.methodMatcher.matches(method,targetClass,arguments))
returndm.interceptor.invoke(this);
else
//否则进行递归调用
returnproceed();
}else
{
//如果是interceptor,直接调用这个interceptor对应的方法
return((MethodInterceptor)interceptorOrInterceptionAdvice).invoke(this);
}
}
那么这个拦截器链的集合是如何产生的呢?
由于AopFactoryBean是继承AdvisedSupport我们在看下AdvisedSupport中的getInterceptorsAndDynamicInterceptionAdvice方法
//获取拦截器
publicListgetInterceptorsAndDynamicInterceptionAdvice(Methodmethod,ClasstargetClass)
{
MethodCacheKeycacheKey=newMethodCacheKey(method);
Listcached=(List)methodCache.get(cacheKey);
if(cached==null)
{
//拦截器链工厂获取
cached=advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(this,method,targetClass);
methodCache.put(cacheKey,cached);
}
returncached;
}
获取拦截器链的工作是由配置好的advisorChainFactory来完成的,在这里advisorChainFactory被配置成一个DefaultAdvisorChainFactory对象,在DefaultAdvisorChainFactory中getInterceptorsAndDynamicInterceptionAdvice方法来获取,源码如下:
publicListgetInterceptorsAndDynamicInterceptionAdvice(Advisedconfig,Methodmethod,ClasstargetClass)
{
//定义拦截器链数组的大小
ListinterceptorList=newArrayList(config.getAdvisors().length);
booleanhasIntroductions=hasMatchingIntroductions(config,targetClass);
//这里采用的简单工厂的方式产生AdvisorAdapterRegistry对象,而该接口的实现类为DefaultAdvisorAdapterRegistry
AdvisorAdapterRegistryregistry=GlobalAdvisorAdapterRegistry.getInstance();
org.springframework.aop.Advisoraadvisor[];
intj=(aadvisor=config.getAdvisors()).length;
for(inti=0;i<j;i++)
{
org.springframework.aop.Advisoradvisor=aadvisor[i];
if(advisorinstanceofPointcutAdvisor)
{
PointcutAdvisorpointcutAdvisor=(PointcutAdvisor)advisor;
if(config.isPreFiltered()||pointcutAdvisor.getPointcut().getClassFilter().matches(targetClass))
{
org.aopalliance.intercept.MethodInterceptorinterceptors[]=registry.getInterceptors(advisor);
MethodMatchermm=pointcutAdvisor.getPointcut().getMethodMatcher();
if(MethodMatchers.matches(mm,method,targetClass,hasIntroductions))
if(mm.isRuntime())
{
org.aopalliance.intercept.MethodInterceptoramethodinterceptor[];
intl=(amethodinterceptor=interceptors).length;
for(intk=0;k<l;k++)
{
org.aopalliance.intercept.MethodInterceptorinterceptor=amethodinterceptor[k];
interceptorList.add(newInterceptorAndDynamicMethodMatcher(interceptor,mm));
}
}else
{
interceptorList.addAll((Collection)Arrays.asList(interceptors));
}
}
}else
if(advisorinstanceofIntroductionAdvisor)
{
IntroductionAdvisoria=(IntroductionAdvisor)advisor;
if(config.isPreFiltered()||ia.getClassFilter().matches(targetClass))
{
org.aopalliance.intercept.Interceptorinterceptors[]=registry.getInterceptors(advisor);
interceptorList.addAll((Collection)Arrays.asList(interceptors));
}
}else
{
org.aopalliance.intercept.Interceptorinterceptors[]=registry.getInterceptors(advisor);
interceptorList.addAll((Collection)Arrays.asList(interceptors));
}
}
returninterceptorList;
}
从上述源码可知:DefaultAdvisorChainFactory会通过一个AdivesorAdatperRegistry来实现拦截器的注册,而这个AdivesorAdatperRegistry对象的advice通知的知入功能起了很大的作用。
Advice通知的实现
我们在看下DefaultAdvisorAdapterRegistry中的getInterceptors方法
//通知适配器集合
privatefinalListadapters=newArrayList(3);
publicMethodInterceptor[]getInterceptors(Advisoradvisor)
throwsUnknownAdviceTypeException
{
Listinterceptors=newArrayList(3);
//从通知器中获取通知
Adviceadvice=advisor.getAdvice();
if(adviceinstanceofMethodInterceptor)
interceptors.add((MethodInterceptor)advice);
for(Iteratoriterator=adapters.iterator();iterator.hasNext();)
{
//循环所有的适配器通知
AdvisorAdapteradapter=(AdvisorAdapter)iterator.next();
if(adapter.supportsAdvice(advice))
interceptors.add(adapter.getInterceptor(advisor));
}
if(interceptors.isEmpty())
thrownewUnknownAdviceTypeException(advisor.getAdvice());
else
return(MethodInterceptor[])interceptors.toArray(newMethodInterceptor[interceptors.size()]);
}
关于通知适配器集合的初始化,通过构造函数注册
//注册advice适配器
publicDefaultAdvisorAdapterRegistry()
{
registerAdvisorAdapter(newMethodBeforeAdviceAdapter());
registerAdvisorAdapter(newAfterReturningAdviceAdapter());
registerAdvisorAdapter(newThrowsAdviceAdapter());
}
//注册方法
publicvoidregisterAdvisorAdapter(AdvisorAdapteradapter)
{
adapters.add(adapter);
}
我们在看一个advice适配器具体实现例如MethodBeforeAdviceAdapter源码
classMethodBeforeAdviceAdapter
implementsAdvisorAdapter,Serializable
{
MethodBeforeAdviceAdapter()
{
}
publicbooleansupportsAdvice(Adviceadvice)
{
returnadviceinstanceofMethodBeforeAdvice;
}
publicMethodInterceptorgetInterceptor(Advisoradvisor)
{
//从中获取advice
MethodBeforeAdviceadvice=(MethodBeforeAdvice)advisor.getAdvice();
//返回拦截器
returnnewMethodBeforeAdviceInterceptor(advice);
}
}