spring AOP源码分析之拦截器

我们都知道在spring AOP中产生代理对象的方式有jdk和cglib的方式生成,无论那种方式,AOP的拦截的处理都是通过ReflectiveMethodInvocation中的proceed方法
其方法的源码如下:
public Object proceed()
throws Throwable
{
//如果拦截器迭代完毕,这里开始调用目标方法
if(currentInterceptorIndex == interceptorsAndDynamicMethodMatchers.size() - 1)
return invokeJoinpoint();
//从拦截器的集合中获取拦截器
Object interceptorOrInterceptionAdvice = interceptorsAndDynamicMethodMatchers.get(++currentInterceptorIndex);
//判断如果是该类型的
if(interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher)
{
InterceptorAndDynamicMethodMatcher dm = (InterceptorAndDynamicMethodMatcher)interceptorOrInterceptionAdvice;
//那么对方法进行匹配
if(dm.methodMatcher.matches(method, targetClass, arguments))
return dm.interceptor.invoke(this);
else
//否则进行递归调用
return proceed();
} else
{
//如果是interceptor,直接调用这个interceptor对应的方法
return ((MethodInterceptor)interceptorOrInterceptionAdvice).invoke(this);
}
}

那么这个拦截器链的集合是如何产生的呢?
由于AopFactoryBean是继承AdvisedSupport我们在看下AdvisedSupport中的getInterceptorsAndDynamicInterceptionAdvice方法
//获取拦截器
public List getInterceptorsAndDynamicInterceptionAdvice(Method method, Class targetClass)
{
MethodCacheKey cacheKey = new MethodCacheKey(method);
List cached = (List)methodCache.get(cacheKey);
if(cached == null)
{
//拦截器链工厂获取
cached = advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(this, method, targetClass);
methodCache.put(cacheKey, cached);
}
return cached;
}
获取拦截器链的工作是由配置好的advisorChainFactory来完成的,在这里advisorChainFactory被配置成一个DefaultAdvisorChainFactory对象,在DefaultAdvisorChainFactory中getInterceptorsAndDynamicInterceptionAdvice方法来获取,源码如下:
public List getInterceptorsAndDynamicInterceptionAdvice(Advised config, Method method, Class targetClass)
{
//定义拦截器链数组的大小
List interceptorList = new ArrayList(config.getAdvisors().length);
boolean hasIntroductions = hasMatchingIntroductions(config, targetClass);
//这里采用的简单工厂的方式产生AdvisorAdapterRegistry对象,而该接口的实现类为DefaultAdvisorAdapterRegistry
AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
org.springframework.aop.Advisor aadvisor[];
int j = (aadvisor = config.getAdvisors()).length;
for(int i = 0; i < j; i++)
{
org.springframework.aop.Advisor advisor = aadvisor[i];
if(advisor instanceof PointcutAdvisor)
{
PointcutAdvisor pointcutAdvisor = (PointcutAdvisor)advisor;
if(config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(targetClass))
{
org.aopalliance.intercept.MethodInterceptor interceptors[] = registry.getInterceptors(advisor);
MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
if(MethodMatchers.matches(mm, method, targetClass, hasIntroductions))
if(mm.isRuntime())
{
org.aopalliance.intercept.MethodInterceptor amethodinterceptor[];
int l = (amethodinterceptor = interceptors).length;
for(int k = 0; k < l; k++)
{
org.aopalliance.intercept.MethodInterceptor interceptor = amethodinterceptor[k];
interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm));
}

} else
{
interceptorList.addAll((Collection)Arrays.asList(interceptors));
}
}
} else
if(advisor instanceof IntroductionAdvisor)
{
IntroductionAdvisor ia = (IntroductionAdvisor)advisor;
if(config.isPreFiltered() || ia.getClassFilter().matches(targetClass))
{
org.aopalliance.intercept.Interceptor interceptors[] = registry.getInterceptors(advisor);
interceptorList.addAll((Collection)Arrays.asList(interceptors));
}
} else
{
org.aopalliance.intercept.Interceptor interceptors[] = registry.getInterceptors(advisor);
interceptorList.addAll((Collection)Arrays.asList(interceptors));
}
}

return interceptorList;
}

从上述源码可知:DefaultAdvisorChainFactory会通过一个AdivesorAdatperRegistry来实现拦截器的注册,而这个AdivesorAdatperRegistry对象的advice通知的知入功能起了很大的作用。


Advice通知的实现
我们在看下DefaultAdvisorAdapterRegistry中的getInterceptors方法

//通知适配器集合
private final List adapters = new ArrayList(3);

public MethodInterceptor[] getInterceptors(Advisor advisor)
throws UnknownAdviceTypeException
{
List interceptors = new ArrayList(3);
//从通知器中获取通知
Advice advice = advisor.getAdvice();
if(advice instanceof MethodInterceptor)
interceptors.add((MethodInterceptor)advice);

for(Iterator iterator = adapters.iterator(); iterator.hasNext();)
{
//循环所有的适配器通知
AdvisorAdapter adapter = (AdvisorAdapter)iterator.next();
if(adapter.supportsAdvice(advice))
interceptors.add(adapter.getInterceptor(advisor));
}

if(interceptors.isEmpty())
throw new UnknownAdviceTypeException(advisor.getAdvice());
else
return (MethodInterceptor[])interceptors.toArray(new MethodInterceptor[interceptors.size()]);
}

关于通知适配器集合的初始化,通过构造函数注册
//注册advice适配器
public DefaultAdvisorAdapterRegistry()
{
registerAdvisorAdapter(new MethodBeforeAdviceAdapter());
registerAdvisorAdapter(new AfterReturningAdviceAdapter());
registerAdvisorAdapter(new ThrowsAdviceAdapter());
}
//注册方法
public void registerAdvisorAdapter(AdvisorAdapter adapter)
{
adapters.add(adapter);
}

我们在看一个advice适配器具体实现例如MethodBeforeAdviceAdapter源码
class MethodBeforeAdviceAdapter
implements AdvisorAdapter, Serializable
{

MethodBeforeAdviceAdapter()
{
}

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

public MethodInterceptor getInterceptor(Advisor advisor)
{
//从中获取advice
MethodBeforeAdvice advice = (MethodBeforeAdvice)advisor.getAdvice();
//返回拦截器
return new MethodBeforeAdviceInterceptor(advice);
}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值