JdkDynamicAopProxy 拦截器链的获得与递归执行
JdkDynamicAopProxy类的invoke方法
1、获得拦截器链
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
进入方法
/**
* Determine a list of {@link org.aopalliance.intercept.MethodInterceptor} objects
* for the given method, based on this configuration.
* @param method the proxied method
* @param targetClass the target class
* @return List of MethodInterceptors (may also include InterceptorAndDynamicMethodMatchers)
*/
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, Class targetClass) {
MethodCacheKey cacheKey = new MethodCacheKey(method);
List<Object> cached = this.methodCache.get(cacheKey);
if (cached == null) {
cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(
this, method, targetClass);
this.methodCache.put(cacheKey, cached);
}
return cached;
}
然后进入getInterceptorsAndDynamicInterceptionAdvice方法
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(
Advised config, Method method, Class targetClass) { // This is somewhat tricky... we have to process introductions first,
// but we need to preserve order in the ultimate list.
List<Object> interceptorList = new ArrayList<Object>(config.getAdvisors().length);
boolean hasIntroductions = hasMatchingIntroductions(config, targetClass);
AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
for (Advisor advisor : config.getAdvisors()) {
if (advisor instanceof PointcutAdvisor) {
// Add it conditionally.
PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(targetClass)) {
MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
if (MethodMatchers.matches(mm, method, targetClass, hasIntroductions)) {
if (mm.isRuntime()) {
// Creating a new object instance in the getInterceptors() method
// isn't a problem as we normally cache created chains.
for (MethodInterceptor interceptor : interceptors) {
interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm));
}
}
else {
interceptorList.addAll(Arrays.asList(interceptors));
}
}
}
}
else if (advisor instanceof IntroductionAdvisor) {
IntroductionAdvisor ia = (IntroductionAdvisor) advisor;
if (config.isPreFiltered() || ia.getClassFilter().matches(targetClass)) {
Interceptor[] interceptors = registry.getInterceptors(advisor);
interceptorList.addAll(Arrays.asList(interceptors));
}
}
else {
Interceptor[] interceptors = registry.getInterceptors(advisor);
interceptorList.addAll(Arrays.asList(interceptors));
}
}
return interceptorList;
}
2、递归
proceed方法

进入proceed方法
目标方法执行之前的一系列的逻辑。
public Object proceed() throws Throwable {
// We start with an index of -1 and increment early.
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return invokeJoinpoint();
}
Object interceptorOrInterceptionAdvice =
this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
// Evaluate dynamic method matcher here: static part will already have
// been evaluated and found to match.
InterceptorAndDynamicMethodMatcher dm =
(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {
return dm.interceptor.invoke(this);
}
else {
// Dynamic matching failed.
// Skip this interceptor and invoke the next in the chain.
return proceed();
}
}
else {
// It's an interceptor, so we just invoke it: The pointcut will have
// been evaluated statically before this object was constructed.
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}
所有的拦截器执行完毕后,执行invokeJoinpoint,调用目标方法
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return invokeJoinpoint();
}
至此,AOP的内容结束了。
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) { return invokeJoinpoint(); }JdkDynamicAopProxy 拦截器链的获得与递归执行的更多相关文章
- spring---aop(3)---Spring AOP的拦截器链
写在前面 时间断断续续,这次写一点关于spring aop拦截器链的记载.至于如何获取spring的拦截器,前一篇博客已经写的很清楚(spring---aop(2)---Spring AOP的JDK动 ...
- Spring异步调用原理及SpringAop拦截器链原理
一.Spring异步调用底层原理 开启异步调用只需一个注解@EnableAsync @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTI ...
- Spring AOP 源码分析 - 拦截器链的执行过程
1.简介 本篇文章是 AOP 源码分析系列文章的最后一篇文章,在前面的两篇文章中,我分别介绍了 Spring AOP 是如何为目标 bean 筛选合适的通知器,以及如何创建代理对象的过程.现在我们的得 ...
- 33、[源码]-AOP原理-获取拦截器链-MethodInterceptor
33.[源码]-AOP原理-获取拦截器链-MethodInterceptor
- SpringBoot系列(十一)拦截器与拦截器链的配置与使用详解,你知道多少?
往期推荐 SpringBoot系列(一)idea新建Springboot项目 SpringBoot系列(二)入门知识 springBoot系列(三)配置文件详解 SpringBoot系列(四)web静 ...
- java 动态代理—— Mybaties 拦截器链基本原理实现
1.摘要 Mybaties 中有个分页插件,之前有特意的去了解了一下原理 :https://www.cnblogs.com/jonrain0625/p/11168247.html,从了解中得知分页插件 ...
- 简单理解Struts2中拦截器与过滤器的区别及执行顺序
简单理解Struts2中拦截器与过滤器的区别及执行顺序 当接收到一个httprequest , a) 当外部的httpservletrequest到来时 b) 初始到了servlet容器 传递给一个标 ...
- 转: Struts2中拦截器与过滤器的区别及执行顺序
当接收到一个httprequest , a) 当外部的httpservletrequest到来时 b) 初始到了servlet容器 传递给一个标准的过滤器链 c) FilterDispatecher会 ...
- AOP-方法拦截器-笔记
方法拦截器的继承层次图: 这些拦截器具体长什么样?? 一.MethodBeforeAdviceInterceptor 这个拦截器只有一个属性就是前置通知.需要注意的是前置通知和返回通知的拦截器才会持有 ...
随机推荐
- sql server快捷键添加
工具--选项--键盘 sp_table_column_info p_helpindex sp_sql
- mariadb远程授权问题
安装mariadb后,使用远程连接时 密码没有问题 但是每次打开都报这个错误: 这个错误是在进行远程连接的时候密码正确, 但是,进行远程授权的时候授权密码错误. 在数据库中执行下述代码即可: GRAN ...
- H3C 802.11b/g工作频段划分图
- Python并发编程-并发解决方案概述
Python并发编程-并发解决方案概述 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.并发和并行区别 1>.并行(parallel) 同时做某些事,可以互不干扰的同一个时 ...
- kubernetes存储之GlusterFS
目录 1.glusterfs概述 1.1.glusterfs简介 1.2.glusterfs特点 1.3.glusterfs卷的模式 2.heketi概述 3.部署heketi+glusterfs 3 ...
- web程序防止攻击的一些资料——整理
地址:https://docs.microsoft.com/en-us/previous-versions/aspnet/a2a4yykt(v=vs.100)?redirectedfrom=MSDN ...
- 关于 ES5 & ES6 数组遍历的方法
ES5 数组遍历方法 1.for 循环 , , , , ] ; i < arr.length; i++) { console.log(arr[i]) } 2.forEach , , , , ] ...
- unix域套接字
对于本地通信,unix域套接字通信是internet通信速度的2倍
- CodeForces - 76A:Gift (最小生成树 解决单调性问题是思想)
题意:给定N点M边的无向连通图,每条边有两个权值(g,s). 给定G,S. 让你给出一组(g0,s0)使得图中仅留下g<=g0, s<=s0的边之后,依然连通,并求Gg0+Ss0的最小值. ...
- Oracle两表关联,只取B表的第一条记录
背景: A表.B表两表关联,关联出来的结果里B表有不止一条,需求是只要B表结果中的某一条(按某字段排序) 首先想到了直接写个带排序的子查询去匹配外围的值,从这个结果集中只要第一条,但是经过验证发现, ...