在上一篇中,我们创建并在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. centos 7 安装及配置zabbix agent

    一.在被监控主机上设置防火墙,允许zabbix-agent的10050端口通过 二.执行yum list |grep zabbix,找到zabbix的agent安装包并安装 三.在 /etc/zabb ...

  2. HDU-4578 Transformation(线段树的多种区间操作)

    http://acm.hdu.edu.cn/showproblem.php?pid=4578 Time Limit: 15000/8000 MS (Java/Others)    Memory Lim ...

  3. selenium登录网银,密码控件输入

    尝试登录农行网银,发现带控件的密码输入框怎么都无法输入啊 最后用虚拟键盘实现的  , DD模拟键盘 http://www.ddxoft.com/ 图形验证码识别没过,有时间再继续 需要安装  Tess ...

  4. AC和路由器

    无线AC控制器是一种网络设备,比如我曾接触过的丰润达的AC100和AC180等,用它们可以来集中控制和管理无线AP,比如下发配置.修改相关配置参数.射频智能管理.接入安全控制等. 路由器是一种连接多个 ...

  5. kubernetes flannel 网卡绑定错误,故障排查

    kubernetes 新加了个node,状态Ready,但调度过去的任务,都执行异常 查看异常节点日志 `Error adding net work: open run/flannel/subnet. ...

  6. Template设计模式

    template英文名叫模板,在这个模式中,主要的角色有AbstractClass(抽象类)和ConcreteClass(具体类),这里举例如下; 将一段字符或者字符串循环显示5次: 首先定义抽象类, ...

  7. hibernate中lazy的使用

    lazy,延迟加载 Lazy的有效期:只有在session打开的时候才有效:session关闭后lazy就没效了. lazy策略可以用在: * <class>标签上:可以取值true/fa ...

  8. python-django框架-电商项目-商品模块开发_20191124

    用户浏览记录的添加 什么时候添加历史浏览记录? 在商品详情的视图里面添加浏览记录, 之前使用的list来存储浏览记录, 注意:如果good_id之前已经浏览过了,那就要移除,conn.lrem(his ...

  9. 3dmax2017卸载/安装失败/如何彻底卸载清除干净3dmax2017注册表和文件的方法

    3dmax2017提示安装未完成,某些产品无法安装该怎样解决呢?一些朋友在win7或者win10系统下安装3dmax2017失败提示3dmax2017安装未完成,某些产品无法安装,也有时候想重新安装3 ...

  10. deeplearning.ai 神经网络和深度学习 week4 深层神经网络

    1. 计算深度神经网络的时候,尽量向量化数据,不要用for循环.唯一用for循环的地方是依次在每一层做计算. 2. 最常用的检查代码是否有错的方法是检查算法中矩阵的维度. 正向传播: 对于单个样本,第 ...