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();
        }

最新文章

  1. 打造android偷懒神器———ListView的万能适配器
  2. 创建Mat对象的几种方法
  3. erlang 健壮性
  4. Linux 命令快捷键
  5. 浅谈 SOLID 原则的具体使用
  6. centos7下使用yum安装mysql数据库以及设置远程访问
  7. linux命令使用记录
  8. CSS transform-style属性实现3D效果
  9. Linux----快速注释包含特定字符串的行
  10. 11gR2 Clusterware and Grid Home - What You Need to Know
  11. poj3468A Simple Problem with Integers(线段树,在段更新时要注意)
  12. php+mysql非缓冲查询(如何循环大数组)
  13. 谈论高并发(二十二)解决java.util.concurrent各种组件(四) 深入了解AQS(二)
  14. JavaScript概要
  15. JAVA调用matlab代码
  16. ArcGis恢复初始设置(默认设置、出厂设置)的方法
  17. kubernetes版本融合解决方案
  18. Hadoop学习之路
  19. djngo 1.9版本以后 Foreignkey() 字段 第二个参数 on_delete 必不可少, mysql 外键可以为空
  20. 阿里八八——预则立&amp;&amp;他山之石

热门文章

  1. React-Native控件的生命周期
  2. MySQL Percona Toolkit--pt-osc重点参数
  3. 【Spring Boot】Spring Boot之统一异常处理
  4. linux系统查看系统内存和硬盘大小
  5. 2013.6.29 - OpenNER第九天
  6. VUE--404页面
  7. 如何在Jenkins中使用日期参数(变量)
  8. 关于base64编码Encode和Decode编码的几种方式
  9. 回调方式进行COM组件对外消息传递
  10. 合并K个有序链表