在上一篇中,我们创建并在BeanFactory中注册了AnnotationAwareAspectJAutoProxyCreator组件。本篇我们将要探究,这个组件是在哪里以及何时发挥作用的。

调试的起点

  我们直接开始调试,之前看过的断点就直接跳过了,一直跳到下一个断点直到来到 AbstractAutoProxyCreator.postProcessBeforeInstantiation()

不同后置处理器的差异

  这个方法名叫postProcessBeforeInstantiation,仔细看会发现和后置处理器BeanPostProcessor是不一样的,我们拉到上面能看到AbstractAutoProxyCreator实现的是

SmartInstantiationAwareBeanPostProcessor这个接口

进入SmartInstantiationAwareBeanPostProcessor这个接口会看到它又继承了InstantiationAwareBeanPostProcessor

再进入InstantiationAwareBeanPostProcessor可以看到它继承的也是BeanPostProcessor

但InstantiationAwareBeanPostProcessor实现的两个方法名字如下:

不同于BeanPostProcessor中的postProcessBeforeInitialization和postProcessAfterInitialization

可见后置处理器也是存在差异的。

结论:AnnotationAwareAspectJAutoProxyCreator是InstantiationAwareBeanPostProcessor类型的后置处理器


从头看起

我们还是从头看起,看程序是怎么走到这一步的。

在Frames框中从测试方法开始,往上查看:

1、refresh刷新创建容器实例化剩下的所有单实例bean

2、finishBeanFactoryInitialization(beanFactory) 实例化剩下的所有单实例bean

3、再往上走,beanFactory调用了preInstantiateSingletons()

4、一直往上走直到AbstractAutowireCapableBeanFactory.createBean(),如下图

  第四步经历了:

    1.   getBean
    2.   doGetBean
    3.   getSingleton
    4.   getObject
    5.   createBean

  这一系列过程和上篇中创建AnnotationAwareAspectJAutoProxyCreator的过程是一模一样的,

  不过上篇创建AnnotationAwareAspectJAutoProxyCreator时,我们经历上述过程后进入的是doCreateBean方法,最终创建出了bean

而在这里,我们执行的是在doCreateBean上面的resolveBeforeInstantiation方法


(这时AnnotationAwareAspectJAutoProxyCreator早已经创建好放入容器,我们现在做的是完成其他所有bean的实例化)

如下图,我们可以发现,当前的resolveBeforeInstantiation正是在doCreateBean方法的上面

说明当时也调用了resolveBeforeInstantiation方法,只不过返回的bean为null,所以才有了调用doCreateBean来创建bean


现在我们可以知道,在所有bean创建之前,都会先调用resolveBeforeInstantiation方法

  方法上的注释表明,方法会给后置处理器一个机会来返回目标bean实例的代理对象。也就是返回一个代理对象来代替我们将要创建的的目标bean

  现在我们把注意力放在resolveBeforeInstantiation这个方法上

  在方法栈中继续往上查看,我们来到了resolveBeforeInstantiation方法的1011行

  从1011到1013行,调用applyBeanPostProcessorsBeforeInstantiation返回bean,接着进行判断,如果返回的bean不为null

  接着执行applyBeanPostProcessorsAfterInitialization方法

  接下来我们先进入applyBeanPostProcessorsBeforeInstantiation方法,将会循环遍历所有的后置处理器

判断如果是InstantiationAwareBeanPostProcessor类型,就执行它的postProcessBeforeInstantiation方法

上面我们提到过后置处理器存在差异,我们的AnnotationAwareAspectJAutoProxyCreator刚好就是属于InstantiationAwareBeanPostProcessor这个类型

所以接下来我们来到当初设置的的后置处理器断点,并执行AnnotationAwareAspectJAutoProxyCreator的postProcessBeforeInstantiation方法

总结

   由以上整个过程,我们可以得出:在所有bean实例化的时候,都会调用AnnotationAwareAspectJAutoProxyCreator的postProcessBeforeInstantiation方法。方法尝试返回一个代理对象,用来代替我们的目标实例。

在下一篇中,我们将探究后置处理器的方法,探究究竟是如何给实例创建代理对象。

spring——AOP原理及源码(三)的更多相关文章

  1. spring——AOP原理及源码(一)

    教程共分为五篇,从AOP实例的构建及其重要组件.基本运行流程.容器创建流程.关键方法调用.原理总结归纳等几个方面一步步走进AOP的世界. 本篇主要为读者演示构建AOP实例及AOP核心组件分析. 一.项 ...

  2. spring——AOP原理及源码(四)

    前情回顾: 上文我们一路分析了从容器创建开始直到我们的AOP注解导入的核心组件AnnotationAwareAspectJAutoProxyCreator执行postProcessBeforeInst ...

  3. spring——AOP原理及源码(五)

    前情回顾: 在上一篇中,通过 wrapIfNecessary 方法,我们获取到了合适的增强器(日志方法)与业务类进行包装,最终返回了我们业务类的代理对象. 本篇我们将从业务方法的执行开始,看看增强器( ...

  4. spring——AOP原理及源码(二)

    回顾: 在上一篇中,我们提到@EnableAspectJAutoProxy注解给容器中加入了一个关键组件internalAutoProxyCreator的BeanDefinition,实际类型为 An ...

  5. 【Spring】Spring IOC原理及源码解析之scope=request、session

    一.容器 1. 容器 抛出一个议点:BeanFactory是IOC容器,而ApplicationContex则是Spring容器. 什么是容器?Collection和Container这两个单词都有存 ...

  6. Spring AOP介绍及源码分析

    转自:http://www.uml.org.cn/j2ee/201301102.asp 软件开发经历了从汇编语言到高级语言和从过程化编程到面向对象编程:前者是为了提高开发效率,而后者则使用了归纳法,把 ...

  7. Spring中AOP原理,源码学习笔记

    一.AOP(面向切面编程):通过预编译和运行期动态代理的方式在不改变代码的情况下给程序动态的添加一些功能.利用AOP可以对应用程序的各个部分进行隔离,在Spring中AOP主要用来分离业务逻辑和系统级 ...

  8. spring MVC 原理及源码解析

    首先要知道springmvc的核心控制器dispatcherServlet(继承自httpServlet) 一般httpServlet的请求过程: 1.初始化(创建servlet实例时)时会执行ser ...

  9. Spring MVC工作原理及源码解析(三) HandlerMapping和HandlerAdapter实现原理及源码解析

    1.HandlerMapping实现原理及源码解析 在前面讲解Spring MVC工作流程的时候我们说过,前端控制器收到请求后会调⽤处理器映射器(HandlerMapping),处理器映射器根据请求U ...

随机推荐

  1. oracle中null的理解

    < EXAMNO STUNO WRITTENEXAM LABEXAM e2014070001 s25301 80 58 e2014070002 s25302 50   e2014070003 s ...

  2. Java接口和抽象类区别

    1.抽象类 [public] abstract class ClassName { abstract void fun(); } extends 包含抽象方法的类称为抽象类,但并不意味着抽象类中只能有 ...

  3. Flask的Jinja2模版过滤器

    Jinja2模版过滤器 过滤器是通过管道符号(|)进行使用的,例如:{{ name|length }},将返回name的长度.过滤器相当于是一个函数,把当前的变量传入到过滤器中,然后过滤器根据自己的功 ...

  4. 第19届亚太零售商大会 | 奇点云CEO行在受邀出席发表演讲

    2019年9月5日—7日,第19届亚太零售商大会在重庆举行. 亚太零售商大会作为世界三大零售盛会之一,是亚太地区零售行业最具规模.最具影响力的零售行业盛会.本次大会以“新零售·新消费·新动力·合作与共 ...

  5. C#阶段小结

    一.数据类型: (一)内建类型: 整型(int ,short, long ,byte ,uint ,ushort, ulong ,sbyte): 浮点型(double float decimal): ...

  6. 做成像的你不得不了解的真相2-灵敏度和QE

    科研级相机的灵敏度由三个主要参数决定: 探测器的QE, 像元尺寸和相机噪声. 后两项我们以后再做专题讨论.这期先讲讲小编认为顶顶重要,看起来最容易理解,但是其实还有些奥妙的QE. QE-量子效率 QE ...

  7. 收集到的技术相关网址——python

    1.Python中常用数据库访问接口模块 专用数据库连接模块——MySQL.SQLite.PostgreSQL.Oracle.IBM DB2.Infomix.Interbase.Sybase.SQL ...

  8. 高可用(keepalived+lvs)

    博主本人平和谦逊,热爱学习,读者阅读过程中发现错误的地方,请帮忙指出,感激不尽 架构图: 本次实验严格按照下图完成 1.系统环境设置 1.1SELinux设置 vim /etc/selinux/con ...

  9. [LC] 54. Spiral Matrix

    Given a matrix of m x n elements (m rows, n columns), return all elements of the matrix in spiral or ...

  10. hosts原理及作用

    https://blog.csdn.net/qq_41356488/article/details/82190372 手机也可以修改hosts,但是需要root权限,百度