AspectJAwareAdvisorAutoProxyCreator 的类图

上图中一些 类/接口 的介绍:

AspectJAwareAdvisorAutoProxyCreator : 公开了AspectJ的调用上下文,并弄清楚来自同一切面的多个Advisor在AspectJ中的优先级规则。

AbstractAdvisorAutoProxyCreator : 通用自动代理创建器,它基于检测到的每个顾问程序为特定bean构建AOP代理。

AbstractAutoProxyCreator : 扩展了 ProxyProcessorSupport,实现了SmartInstantiationAwareBeanPostProcessor、BeanFactoryAware 接口,是BeanPostProcessor 实现,该实现使用AOP代理包装每个合格的bean,并在调用bean本身之前委派给指定的拦截器。

BeanFactoryAware : 实现了该接口的Bean可以知道它属于那个 BeanFactory,Bean可以通过Spring容器查找它的协同者(依赖查找),但大多数的Bean是通过构造器参数和Bean方法(依赖注入)来获取它的协同者。

BeanPostProcessor :工厂钩子,允许自定义修改新的bean实例。例如,检查标记接口或使用代理包装bean。如果我们需要在Spring容器中完成Bean的实例化,配置和其初始化前后添加一些自己的逻辑处理,我们就可以定义一个或多个BeanPostProcessor接口的实现,然后注册到容器中。

InstantiationAwareBeanPostProcessor :  BeanPostProcessor 的子接口,它添加了实例化之前的回调,以及实例化之后但设置了显式属性或自动装配之前的回调。它内部提供了3个方法,再加上BeanPostProcessor接口内部的2个方法,实现这个接口需要实现5个方法。InstantiationAwareBeanPostProcessor 接口的主要作用在于目标对象的实例化过程中需要处理的事情,包括实例化对象的前后过程以及实例的属性设置。

SmartInstantiationAwareBeanPostProcessor : InstantiationAwareBeanPostProcessor 接口的扩展,多出了3个方法,添加了用于预测已处理bean的最终类型的回调,再加上父接口的5个方法,所以实现这个接口需要实现8个方法,主要作用也是在于目标对象的实例化过程中需要处理的事情。

AspectJAwareAdvisorAutoProxyCreator为 AspectJ 切面类创建自动代理。

  BeanPostProcessor 接口中的两个方法 postProcessBeforeInitialization 和 postProcessAfterInitialization,作用是对Bean初始化前后添加一些自己的逻辑。

  1. 1 @Nullable
  2. 2 default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
  3. 3 return bean;
  4. 4 }
  5. 5
  6. 6 @Nullable
  7. 7 default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
  8. 8 return bean;
  9. 9 }

  InstantiationAwareBeanPostProcessor 是 BeanPostProcessor 的子接口,它额外增加了3个新的方法:postProcessBeforeInstantiation( 目标对象被实例化之前调用的方法,可以返回目标实例的一个代理用来代替目标实例 )、postProcessAfterInstantiation(该方法在Bean实例化之后执行,返回false,会忽略属性值的设置;如果返回true,会按照正常流程设置属性值) 和 postProcessPropertyValues(对属性值进行修改,未来版本将会删除)。

  1. 1 @Nullable
  2. 2 default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
  3. 3 return null;
  4. 4 }
  5. 5
  6. 6 default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
  7. 7 return true;
  8. 8 }
  9. 9
  10. 10 @Nullable
  11. 11 default PropertyValues postProcessPropertyValues(
  12. 12 PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
  13. 13
  14. 14 return pvs;
  15. 15 }

  SmartInstantiationAwareBeanPostProcessor接口继承InstantiationAwareBeanPostProcessor接口,里面定义了3个方法:predictBeanType(预测Bean的类型)、determineCandidateConstructors(选择合适的构造器)、getEarlyBeanReference(解决循环引用问题)。

  1. 1 @Nullable
  2. 2 default Class<?> predictBeanType(Class<?> beanClass, String beanName) throws BeansException {
  3. 3 return null;
  4. 4 }
  5. 5
  6. 6 @Nullable
  7. 7 default Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName) throws BeansException {
  8. 8 return null;
  9. 9 }
  10. 10
  11. 11 default Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
  12. 12 return bean;
  13. 13 }

  AbstractAutoProxyCreator 是AOP的一个核心类,它实现了SmartInstantiationAwareBeanPostProcessor、BeanFactoryAware 接口,实现了代理创建的逻辑,使用AOP代理包装每个合格的bean,并在调用bean本身之前委派给指定的拦截器。

  AbstractAdvisorAutoProxyCreator 通用自动代理创建器,它基于检测每个bean的增强器,为特殊的bean构建AOP代理。子类可以重写此findCandidateAdvisors()方法,以返回适用于任何对象的advisor的自定义列表,子类还可以重写继承的AbstractAutoProxyCreator.shouldSkip()方法,以将某些对象排除在自动代理之外。

  1. 1 protected List<Advisor> findCandidateAdvisors() {
  2. 2 Assert.state(this.advisorRetrievalHelper != null, "No BeanFactoryAdvisorRetrievalHelper available");
  3. 3 return this.advisorRetrievalHelper.findAdvisorBeans();
  4. 4 }

  AspectJAwareAdvisorAutoProxyCreator 扩展 AbstractAdvisorAutoProxyCreator,公开了AspectJ的调用上下文,并在多个增强器来自同一切面时搞清楚AspectJ的建议优先级顺序。按AspectJ优先级排序其余部分:

  1. 1 @Override
  2. 2 @SuppressWarnings("unchecked")
  3. 3 protected List<Advisor> sortAdvisors(List<Advisor> advisors) {
  4. 4 List<PartiallyComparableAdvisorHolder> partiallyComparableAdvisors = new ArrayList<>(advisors.size());
  5. 5 for (Advisor element : advisors) {
  6. 6 partiallyComparableAdvisors.add(
  7. 7 new PartiallyComparableAdvisorHolder(element, DEFAULT_PRECEDENCE_COMPARATOR));
  8. 8 }
  9. 9 List<PartiallyComparableAdvisorHolder> sorted = PartialOrder.sort(partiallyComparableAdvisors);
  10. 10 if (sorted != null) {
  11. 11 List<Advisor> result = new ArrayList<>(advisors.size());
  12. 12 for (PartiallyComparableAdvisorHolder pcAdvisor : sorted) {
  13. 13 result.add(pcAdvisor.getAdvisor());
  14. 14 }
  15. 15 return result;
  16. 16 }
  17. 17 else {
  18. 18 return super.sortAdvisors(advisors);
  19. 19 }
  20. 20 }

  在增强链头部增加一个ExposeInvocationInterceptor,使用AspectJ表达式切入点和使用AspectJ样式的advisor时,需要这些附加advisor。

  1. 1 protected void extendAdvisors(List<Advisor> candidateAdvisors) {
  2. 2 AspectJProxyUtils.makeAdvisorChainAspectJCapableIfNecessary(candidateAdvisors);
  3. 3 }

  如果此后处理器不应该考虑将给定的bean用于自动代理,子类应重写此方法以返回true

  1. 1 @Override
  2. 2 protected boolean shouldSkip(Class<?> beanClass, String beanName) {
  3. 3 // TODO: Consider optimization by caching the list of the aspect names
  4. 4 List<Advisor> candidateAdvisors = findCandidateAdvisors();
  5. 5 for (Advisor advisor : candidateAdvisors) {
  6. 6 if (advisor instanceof AspectJPointcutAdvisor &&
  7. 7 ((AspectJPointcutAdvisor) advisor).getAspectName().equals(beanName)) {
  8. 8 return true;
  9. 9 }
  10. 10 }
  11. 11 return super.shouldSkip(beanClass, beanName);
  12. 12 }

  AspectJAwareAdvisorAutoProxyCreator 还有一个子类叫 AnnotationAwareAspectJAutoProxyCreator,子类AnnotationAwareAspectJAutoProxyCreator是用于处理当前应用程序上下文中的所有AspectJ注释方面以及Spring Advisor。如果Spring AOP的基于代理的模型能够应用任何AspectJ注释的类,它们的advisor将被自动识别,这涵盖了方法执行连接点,Spring Advisor的处理遵循AbstractAdvisorAutoProxyCreator中建立的规则。

生成代理对象

  从使用<aop:xxx>标签来自动生成代理的话,先看看AopNamespaceHandler,使用<aop:config>标签则使用 ConfigBeanDefinitionParser 解析,使用了<aop:aspectj-autoproxy>标签则使用 AspectJAutoProxyBeanDefinitionParser 解析,依次类推。

  1. 1 @Override
  2. 2 public void init() {
  3. 3 // In 2.0 XSD as well as in 2.1 XSD.
  4. 4 registerBeanDefinitionParser("config", new ConfigBeanDefinitionParser());
  5. 5 registerBeanDefinitionParser("aspectj-autoproxy", new AspectJAutoProxyBeanDefinitionParser());
  6. 6 registerBeanDefinitionDecorator("scoped-proxy", new ScopedProxyBeanDefinitionDecorator());
  7. 7
  8. 8 // Only in 2.0 XSD: moved to context namespace as of 2.1
  9. 9 registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser());
  10. 10 }
  • <aop:config>方式使用 AspectJAwareAdvisorAutoProxyCreator 创建代理

  • <aop:aspectj-autoproxy>使用 AnnotationAwareAspectJAutoProxyCreator 创建代理

ConfigBeanDefinitionParser.java

  1. 1 @Override
  2. 2 @Nullable
  3. 3 public BeanDefinition parse(Element element, ParserContext parserContext) {
  4. 4 CompositeComponentDefinition compositeDef =
  5. 5 new CompositeComponentDefinition(element.getTagName(), parserContext.extractSource(element));
  6. 6 parserContext.pushContainingComponent(compositeDef);
  7. 7
  8. 8 configureAutoProxyCreator(parserContext, element); // 注册AspectJAwareAdvisorAutoProxyCreator
  9. 9
  10. 10 List<Element> childElts = DomUtils.getChildElements(element);
  11. 11 for (Element elt: childElts) {
  12. 12 String localName = parserContext.getDelegate().getLocalName(elt);
  13. 13 if (POINTCUT.equals(localName)) {
  14. 14 parsePointcut(elt, parserContext);
  15. 15 }
  16. 16 else if (ADVISOR.equals(localName)) {
  17. 17 parseAdvisor(elt, parserContext);
  18. 18 }
  19. 19 else if (ASPECT.equals(localName)) {
  20. 20 parseAspect(elt, parserContext);
  21. 21 }
  22. 22 }
  23. 23
  24. 24 parserContext.popAndRegisterContainingComponent();
  25. 25 return null;
  26. 26 }
  27. 27
  28. 28 private void configureAutoProxyCreator(ParserContext parserContext, Element element) {
  29. 29 AopNamespaceUtils.registerAspectJAutoProxyCreatorIfNecessary(parserContext, element);
  30. 30 }

AopConfigUtils.java

  1. 1 public static void registerAspectJAutoProxyCreatorIfNecessary(
  2. 2 ParserContext parserContext, Element sourceElement) {
  3. 3    // 在这里注册的是AspectJAwareAdvisorAutoProxyCreator
  4. 4 BeanDefinition beanDefinition = AopConfigUtils.registerAspectJAutoProxyCreatorIfNecessary(
  5. 5 parserContext.getRegistry(), parserContext.extractSource(sourceElement));
  6. 6 useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement);
  7. 7 registerComponentIfNecessary(beanDefinition, parserContext); // 注册组件
  8. 8 }
  1. 1 @Nullable
  2. 2 public static BeanDefinition registerAspectJAutoProxyCreatorIfNecessary(
  3. 3 BeanDefinitionRegistry registry, @Nullable Object source) {
  4. 4
  5. 5 return registerOrEscalateApcAsRequired(AspectJAwareAdvisorAutoProxyCreator.class, registry, source);
  6. 6 }

  AspectJAwareAdvisorAutoProxyCreator 实现了 BeanPostProcessor 等上面介绍的接口,主要作用于Bean初始化前后,实例化前后,所有的Bean都被作用到。InstantiationAwareBeanPostProcessor 是 BeanPostProcessor的子接口,但它的调用时间点发生在Bean实例化前,在真正调用doCreateBean()创建bean实例之前执行postProcessBeforeInstantiation()。

AbstractAutoProxyCreator.java

  1. 1 @Override
  2. 2 public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
  3. 3 Object cacheKey = getCacheKey(beanClass, beanName);  // 得到一个缓存的唯一key(根据beanClass和beanName生成唯一key)
  4. 4      // 如果当前targetSourcedBeans(通过自定义TargetSourceCreator创建的TargetSource)不包含cacheKey
  5. 5 if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
  6. 6 if (this.advisedBeans.containsKey(cacheKey)) {  //advisedBeans(已经被增强的Bean,即AOP代理对象)中包含当前cacheKey,返回null,即走Spring默认流程
  7. 7 return null;
  8. 8 }
  9. 9 if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {// 如果是基础设施类(如Advisor、Advice、AopInfrastructureBean的实现)不进行处理;(略)
  10. 10 this.advisedBeans.put(cacheKey, Boolean.FALSE);
  11. 11 return null;
  12. 12 }
  13. 13 }
  14. 14
  15. 15 // 如果有自定义的TargetSource,在此处创建代理
  16. 16 // 禁止目标Bean的不必要的默认实例化:
  17. 17 // TargetSource将以自定义方式处理目标实例。
  18. 18 TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
  19. 19 if (targetSource != null) {
  20. 20 if (StringUtils.hasLength(beanName)) {
  21. 21 this.targetSourcedBeans.add(beanName);
  22. 22 }
  23. 23 Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
  24. 24 Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
  25. 25 this.proxyTypes.put(cacheKey, proxy.getClass());
  26. 26 return proxy;
  27. 27 }
  28. 28
  29. 29 return null;
  30. 30 }

通过 AbstractAutoProxyCreator 中的 postProcessAfterInitialization() 创建AOP代理。

  1. 1 @Override
  2. 2 public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) throws BeansException {
  3. 3 if (bean != null) {
  4. 4 Object cacheKey = getCacheKey(bean.getClass(), beanName);
  5. 5 if (!this.earlyProxyReferences.contains(cacheKey)) {  // 如果之前调用过getEarlyBeanReference获取包装目标对象到AOP代理对象(如果需要),则不再执行
  6. 6 return wrapIfNecessary(bean, beanName, cacheKey);  // 包装目标对象到AOP代理对象(如果需要)
  7. 7 }
  8. 8 }
  9. 9 return bean;
  10. 10 }
  11. 11
  12. 12 protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
  13. 13 if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) { // 通过TargetSourceCreator进行自定义TargetSource不需要包装
  14. 14 return bean;
  15. 15 }
  16. 16 if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {  // 不应该被增强对象不需要包装
  17. 17 return bean;
  18. 18 }
  19. 19 if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) { // 基础设施或应该skip的不需要保证
  20. 20 this.advisedBeans.put(cacheKey, Boolean.FALSE);
  21. 21 return bean;
  22. 22 }
  23. 23
  24. 24 // 如果有advise则创建代理。
  25. 25 Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
  26. 26 if (specificInterceptors != DO_NOT_PROXY) {
  27. 27 this.advisedBeans.put(cacheKey, Boolean.TRUE);
  28. 28 Object proxy = createProxy(
  29. 29 bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean)); // 创建代理对象
  30. 30 this.proxyTypes.put(cacheKey, proxy.getClass());
  31. 31 return proxy;
  32. 32 }
  33. 33
  34. 34 this.advisedBeans.put(cacheKey, Boolean.FALSE);
  35. 35 return bean;
  36. 36 }

参考:

Spring内部的BeanPostProcessor接口总结

【Spring源码分析】AOP源码解析(下篇)

AOP源码解析:AspectJAwareAdvisorAutoProxyCreator类的介绍的更多相关文章

  1. AOP源码解析之二-创建AOP代理前传,获取AOP信息

    AOP源码解析之二-创建AOP代理前传,获取AOP信息. 上篇文章对AOP的基本概念说清楚了,那么接下来的AOP还剩下两个大的步骤获取定义的AOP信息,生成代理对象扔到beanFactory中. 本篇 ...

  2. 老生常谈系列之Aop--Spring Aop源码解析(二)

    老生常谈系列之Aop--Spring Aop源码解析(二) 前言 上一篇文章老生常谈系列之Aop--Spring Aop源码解析(一)已经介绍完Spring Aop获取advice切面增强方法的逻辑, ...

  3. 老生常谈系列之Aop--Spring Aop源码解析(一)

    老生常谈系列之Aop--Spring Aop源码解析(一) 前言 上一篇文章老生常谈系列之Aop--Spring Aop原理浅析大概阐述了动态代理的相关知识,并且最后的图给了一个Spring Aop实 ...

  4. 【Spring源码分析】AOP源码解析(上篇)

    前言 前面写了六篇文章详细地分析了Spring Bean加载流程,这部分完了之后就要进入一个比较困难的部分了,就是AOP的实现原理分析.为了探究AOP实现原理,首先定义几个类,一个Dao接口: pub ...

  5. 第四章 dubbo内核之aop源码解析

    ExtensionLoader<Protocol> loader = ExtensionLoader.getExtensionLoader(Protocol.class); final P ...

  6. Spring系列(五):Spring AOP源码解析

    一.@EnableAspectJAutoProxy注解 在主配置类中添加@EnableAspectJAutoProxy注解,开启aop支持,那么@EnableAspectJAutoProxy到底做了什 ...

  7. [Java源码解析] -- String类的compareTo(String otherString)方法的源码解析

    String类下的compareTo(String otherString)方法的源码解析 一. 前言 近日研究了一下String类的一些方法, 通过查看源码, 对一些常用的方法也有了更透彻的认识,  ...

  8. Spring源码解析——核心类介绍

    前言: Spring用了这么久,虽然Spring的两大核心:IOC和AOP一直在用,但是始终没有搞懂Spring内部是怎么去实现的,于是决定撸一把Spring源码,前前后后也看了有两边,很多东西看了就 ...

  9. AOP源码解析:AspectJExpressionPointcutAdvisor类

    先看看 AspectJExpressionPointcutAdvisor 的类图 再了解一下切点(Pointcut)表达式,它指定触发advice的方法,可以精确到返回参数,参数类型,方法名 1 pa ...

随机推荐

  1. 在linux查询本机的公网IP

    linux服务器查看公网IP信息的方法 最近在解决网络问题时,需要查看本机的出口公网IP信息,所以在网络上搜索和请求运维达人,获得如下两个方法: curl ifconfig.me 在linux系统中输 ...

  2. 技术栈:springboot2.x,vue,activiti5.22,mysql,带工作流系统

    前言 activiti工作流,企业erp.oa.hr.crm等审批系统轻松落地,请假审批demo从流程绘制到审批结束实例. 一.项目形式 springboot+vue+activiti集成了activ ...

  3. [NOIP2015 普及组] 扫雷游戏

    [NOIP2015 普及组] 扫雷游戏 难度:入门 题目描述 扫雷游戏是一款十分经典的单机小游戏.在nn行mm列的雷区中有一些格子含有地雷(称之为地雷格),其他格子不含地雷(称之为非地雷格).玩家翻开 ...

  4. 解决sofaboot项目右键入口方法没有run sofa application

    选中入口方法名,右键出现run sofa application

  5. Python测试框架对比----unittest, pytest, nose, robot framework对比

    什么是框架? 框架(Framework)是整个或部分系统的可重用设计, 框架是用来解决代码的组织及运行控制问题的. 在我们编写自动化脚本的时候,经常需要读取配置文件,读取数据文件,发送请求,记录日志, ...

  6. C++ 找零钱方法数

    * 动态规划法 #include "stdafx.h" #include <iostream> #include <vector> using std::v ...

  7. @RestController的用法

    我一直都不太理解RESTFUL风格但是先记住一些基本用法在深入吧 ** * * 在服务端应用程序状态和功能可以分成各种资源,每一个资源都使用URL 得到一个唯一的地址,所有资源都共享统一的 * 接口, ...

  8. 鸿蒙内核源码分析(原子操作篇) | 是谁在为原子操作保驾护航 | 百篇博客分析OpenHarmony源码 | v34.02

    百篇博客系列篇.本篇为: v34.xx 鸿蒙内核源码分析(原子操作篇) | 谁在为原子操作保驾护航 | 51.c.h .o 本篇说清楚原子操作 读本篇之前建议先读鸿蒙内核源码分析(总目录)系列篇. 基 ...

  9. Jmeter压测学习4--XPath提取器

    没有遇到,直接转载:https://www.cnblogs.com/yoyoketang/p/11962553.html 前言 有些web项目是前后端不分离的,返回的内容不是那种纯进口返回json格式 ...

  10. 使用gitlab runner进行CI(三):使用sonarqube做c++的静态检查

    目录 1. gitlab-ci.yml的配置 1.1 几个基本概念 1.2 使用CI进行代码检查demo 2. Sonarqube安装和配置 2.1 Sonarqube安装 2.2 数据库配置 2.3 ...