在上一章节中,我们已经知道了如何获取增强器,但是我们还一件事还未做,那就是寻找匹配的增强器。下面我们来看这个功能的时序图。

1. AbstractAdvisorAutoProxyCreator

在AbstractAdvisorAutoProxyCreator的类,重点实现寻找匹配的增强器是在方法findAdvisorsThatCanApply中。

protected List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {ProxyCreationContext.setCurrentProxiedBeanName(beanName);try {return AopUtils.<strong>findAdvisorsThatCanApply(candidateAdvisors, beanClass)</strong>;}finally {ProxyCreationContext.setCurrentProxiedBeanName(null);}}

2. AopUtils

我们继续跟踪代码的findAdvisorsThatCanApply的方法,进入代码可以看到,这里主要做的事情是处理引介增强、对于普通bean的处理。

public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {if (candidateAdvisors.isEmpty()) {return candidateAdvisors;}List<Advisor> eligibleAdvisors = new LinkedList<Advisor>();for (Advisor candidate : candidateAdvisors) {if (candidate instanceof IntroductionAdvisor && <strong>canApply(candidate, clazz)</strong>) {eligibleAdvisors.add(candidate);}}boolean hasIntroductions = !eligibleAdvisors.isEmpty();for (Advisor candidate : candidateAdvisors) {if (candidate instanceof IntroductionAdvisor) {// already processedcontinue;}if (canApply(candidate, clazz, hasIntroductions)) {eligibleAdvisors.add(candidate);}}return eligibleAdvisors;}

findAdvisorsThatCanApply函数的主要功能是寻找所有增强器中适用于当前class的增强器。而对于正确的匹配就是由canApply方法来实现。

public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) {if (advisor instanceof IntroductionAdvisor) {return ((IntroductionAdvisor) advisor).getClassFilter().matches(targetClass);}else if (advisor instanceof PointcutAdvisor) {PointcutAdvisor pca = (PointcutAdvisor) advisor;return <strong>canApply(pca.getPointcut(), targetClass, hasIntroductions)</strong>;}else {// It doesn't have a pointcut so we assume it applies.return true;}}

上面的return canApply(pca.getPointcut(),targetClass,hasIntroductions)的方法其实是调用下面的canApply的方法。

public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {Assert.notNull(pc, "Pointcut must not be null");if (!pc.getClassFilter().matches(targetClass)) {return false;}MethodMatcher methodMatcher = pc.getMethodMatcher();IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;if (methodMatcher instanceof IntroductionAwareMethodMatcher) {introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher;}Set<Class<?>> classes = new LinkedHashSet<Class<?>>(ClassUtils.getAllInterfacesForClassAsSet(targetClass));classes.add(targetClass);for (Class<?> clazz : classes) {Method[] methods = clazz.getMethods();for (Method method : methods) {if ((introductionAwareMethodMatcher != null &&introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions)) ||methodMatcher.matches(method, targetClass)) {return true;}}}return false;}

3.总结

Spring的AOP代理,其中所要做的事情无非就是两步:获取增强方法或者增强器,和根据获取的增强进行代理。当然,对于获取增强方法或增强器,思路如下:

1)        获取所有beanName,这一步骤所有在beanFactory中注册的Bean都会被提取出来。

2)        遍历所有beanName,并找出声明AspectJ注解的类,进行进一步的处理

3)        对标记为AspectJ注解的类进行增强的提取

4)        将提取结果加入缓存

Spring源码之创建AOP代理(补)相关推荐

  1. Spring源码分析之AOP源码分析

    文章目录 前言 一.AOP回顾 二.源码分析 EnableAspectJAutoProxy注解 AnnotationAwareAspectJAutoProxyCreator 前言 Spring框架的两 ...

  2. Spring源码深度解析(郝佳)-学习-源码解析-创建AOP静态代理实现(八)

    继上一篇博客,我们继续来分析下面示例的 Spring 静态代理源码实现. 静态 AOP使用示例 加载时织入(Load -Time WEaving,LTW) 指的是在虚拟机载入字节码时动态织入 Aspe ...

  3. Spring 源码分析(三) —— AOP(五)创建代理

    2019独角兽企业重金招聘Python工程师标准>>> 创建代理 代理的定义其实非常简单,就是改变原来目标对象方法调用的运行轨迹.这种改变,首先会对这些方法进行拦截,从而为这些方法提 ...

  4. Spring源码深度解析(郝佳)-学习-源码解析-创建AOP静态代理(七)

    加载时织入(Load-Time Weaving ,LTW) 指的是在虚拟机加载入字节码文件时动态织入Aspect切面,Spring框架的值添加为 AspectJ LTW在动态织入过程中提供了更细粒度的 ...

  5. Spring 源码分析(三) —— AOP(二)Spring AOP 整体架构

    2019独角兽企业重金招聘Python工程师标准>>> Spring AOP 架构         先是生成代理对象,然后是拦截器的作用,最后是编织的具体实现.这是AOP实现的三个步 ...

  6. spring源码分析之Aop

    今天读spring源码,读到aop相关内容,在此记录一下,以便以后复习和查阅. 一.spring如何实现Aop 这里简单的说下原理,spring实例化bean要经历一套完整的生命周期,在这个过程中会对 ...

  7. Spring源码浅析之AOP、Aspect、Advice

    前言 理一理AOP与切面(Aspect).通知(Advice)的关系 概念 通知(Advice): AOP 框架中的增强处理.通知描述了切面何时执行以及如何执行增强处理. 连接点(join point ...

  8. Spring源码分析之Aop中拦截器,适配器,通知之间的关系

    首先举一个例子: public class MethodBeforeAdviceInterceptor implements MethodInterceptor, Serializable {priv ...

  9. Spring源码追踪3——AOP机制

    研究代码: spring配置文件 <cache:annotation-driven /> Java代码 @Cacheable(value = "test", key = ...

  10. spring源码阅读--aop实现原理分析

    aop实现原理简介 首先我们都知道aop的基本原理就是动态代理思想,在设计模式之代理模式中有介绍过这两种动态代理的使用与基本原理,再次不再叙述. 这里分析的是,在spring中是如何基于动态代理的思想 ...

最新文章

  1. 8月第1周安全回顾 0Day漏洞成企业最大威胁 应重视网络监听
  2. Windows Server 2008组策略安全实践手册
  3. linux字符设备led驱动源码,字符设备驱动控制LED灯
  4. 小而美的个人博客——后端——管理页面
  5. Java Web项目,Android和微信小程序的初始页面配置
  6. 阿里云天池 Python训练营Task2: Python基础练习:数据结构大汇总 学习笔记
  7. vue中用数组语法绑定class
  8. 4 CO配置-企业结构-分配-把控制范围分配给经营范围
  9. 文件字符输入流 java
  10. python字符串操作_Python 字符串操作 - 树懒学堂
  11. 10安装报错0x8007000d_windows10:MySQL8.0.22版本安装教程
  12. 关于模电与数电的基础知识
  13. 基于python的会议室预约管理系统的设计与实现
  14. java beetl输出demo_Beetl 快速入门
  15. ubuntu14.04下deb文件安装mysql数据库
  16. JAVA 使用POI读取文档
  17. 口语8000句--(2)生病、受伤时
  18. STM32系列(HAL库)——F103C8T6点亮1.44寸TFT-LCD彩屏
  19. 人民币小写转大写的一般方法
  20. 开源社区“大牛”关于“开源”的大讨论

热门文章

  1. 【effective c++】资源管理
  2. Handlebars 和 angularjs 之间的区别
  3. (原创)一个简洁通用的调用DLL函数的帮助类
  4. docker volume mysql_docker volume的理解
  5. Security+ 学习笔记30 云计算构建模块
  6. 三、K8s常见操作命令
  7. 华三 h3c Vlan静态路由
  8. mongodb C++ Driver安装
  9. 冰点密码忘记了怎么办
  10. 算法基础练习--最大公约数和最小公倍数