我们都知道在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);
}
}
分享到:
相关推荐
Spring源代码解析(七):Spring AOP中对拦截器调用的实现 Spring源代码解析(八):Spring驱动Hibernate的实现 Spring源代码解析(九):Spring Acegi框架鉴权的实现 Spring源代码解析(十):Spring Acegi框架授权...
Spring源代码解析(七):Spring AOP中对拦截器调用的实现 8. Spring源代码解析(八):Spring驱动Hibernate的实现 9.Spring源代码解析(九):Spring Acegi框架鉴权的实现 10. Spring源代码解析(十):Spring ...
Spring源代码解析(七):Spring AOP中对拦截器调用的实现.doc Spring源代码解析(八):Spring驱动Hibernate的实现.doc Spring源代码解析(九):Spring Acegi框架鉴权的实现.doc Spring源代码解析(十):Spring ...
Spring源代码解析(七):Spring AOP中对拦截器调用的实现 Spring源代码解析(八):Spring驱动Hibernate的实现 Spring源代码解析(九):Spring Acegi框架鉴权的实现 Spring源代码解析(十):Spring Acegi框架授权...
讲解了3种AOP的开发方式,即使用@Aspect注释符、基于Schema的配置的开发方式和Spring API的开发方式,最后在实际的Java EE项目中实现5种Spring AOP功能(日志记录器、性能分析器、权限检查拦截器、异常监视器、在线...
在Spring中,事务管理是通过一系列的拦截器和事务管理器来实现的。当一个被@Transactional注解的方法被调用时,Spring会创建一个代理来包装该方法,确保事务的正确开始和结束。这种代理机制基于Spring AOP实现,能够...
该文档是SSH框架为基础实现的BBS论坛。其中有整合好的全面的SSH jar包,BBS前台,后台源码,这个小系统的报告,数据库关系分析等。 以下内容摘自报告目录部分(希望...4.14 根据权限定义拦截器 4.15 测试系统相应的功能
该文档是SSH框架为基础实现的BBS论坛。其中有整合好的全面的SSH jar包,BBS前台,后台源码,这个小系统的报告,数据库关系分析等。 以下内容摘自报告目录部分(希望...4.14 根据权限定义拦截器 4.15 测试系统相应的功能
│ Java面试题49.Struts2的拦截器是什么?你都用它干什么?.mp4 │ Java面试题50.Spring MVC的执行流程.mp4 │ Java面试题51.SpringMVC和Struts2的不同.mp4 │ Java面试题52.简单介绍一下Spring或者Spring的两大核心...
通过拦截器实现了方法级粒度的鉴权,通过AOP实现了参数校验。 --------------------------- **演示**:[https://small.ડ.com/][1] 可自行注册账号,或使用后台查看权限账号 demo 密码 demo (后台入口登陆后显示...
正式发布表达式计算引擎WfcExp V0.9(附源码) 运算表达式类的原理及其实现 #实现的18位身份证格式验证算法 身份证15To18 的算法(C#) 一组 正则表达式 静态构造函数 忽略大小写Replace效率瓶颈IndexOf 随机排列算法 ...