spring源码解析(四)-registerBeanPostProcessors

 

介绍:

上节我们介绍了invokeBeanFactoryPostProcessors方法,

这篇文章将重点解析refresh中的另一个重要方法---registerBeanPostProcessors

invokeBeanFactoryPostProcessors 方法主要用于处理 BeanFactoryPostProcessor 接口,而 registerBeanPostProcessors 方法主要用于处理 BeanPostProcessor 接口。BeanFactoryPostProcessor 和 BeanPostProcessor,这两个接口接口很像。BeanFactoryPostProcessor 是针对 BeanFactory 的扩展,主要用在 bean 实例化之前,读取 bean 的定义,并可以修改它。BeanPostProcessor 是针对 bean 的扩展,主要用在 bean 实例化之后,执行初始化方法前后。。。

允许开发者对 bean 实例进行修改

(注:也有一些比较特殊的BeanPostProcessor 是在实例化前后去做调用的,比如aop的生成代理的功能,就是在 被代理的类实例化后去生成代理对象的。。。BeanPostProcessor 有两个方法 postBefore 和postAtfer

这里和BeanFactoryPostProcessor有点区别,,BeanFactoryPostProcessor通常只有postAfter方法。

 

概述:

本方法会注册所有的 BeanPostProcessor,将所有实现了 BeanPostProcessor 接口的类加载到 BeanFactory 中。

BeanPostProcessor 接口是 Spring 初始化 bean 时对外暴露的扩展点,Spring IoC 容器允许 BeanPostProcessor 在容器初始化 bean 的前后,添加自己的逻辑处理。在 registerBeanPostProcessors 方法只是注册到 BeanFactory 中,具体调用是在 bean 初始化的时候。

具体的:在所有 bean 实例化时,执行初始化方法前会调用所有 BeanPostProcessor 的 postProcessBeforeInitialization 方法,在执行初始化方法后会调用所有 BeanPostProcessor 的 postProcessAfterInitialization 方法。

 

正文:

okay,

我们来到 AbstractApplicationContext.refresh() 方法,代码:registerBeanPostProcessors(beanFactory),

单击该行代码跳转到具体的实现

spring源码解析(四)-registerBeanPostProcessors_第1张图片

1.注册 BeanPostProcessor,见代码块1详解

代码块1:registerBeanPostProcessors

spring源码解析(四)-registerBeanPostProcessors_第2张图片

 

spring源码解析(四)-registerBeanPostProcessors_第3张图片

 

spring源码解析(四)-registerBeanPostProcessors_第4张图片

 

spring源码解析(四)-registerBeanPostProcessors_第5张图片

spring源码解析(四)-registerBeanPostProcessors_第6张图片

5.1 对 priorityOrderedPostProcessors进行排序,,在invokeBeanFactoryPostProcessors文章中 代码中3已经解析过。

5.2 注册 priorityOrderedPostProcessors,见代码块2详解

代码块2:registerBeanPostProcessors

 

spring源码解析(四)-registerBeanPostProcessors_第7张图片

2.将 PostProcessor 添加到 BeanFactory 中的 beanPostProcessors 缓存,见代码块3详解

代码块3:beanFactory.addBeanPostProcessor

spring源码解析(四)-registerBeanPostProcessors_第8张图片

该方法作用就是将 BeanPostProcessor 添加到 beanPostProcessors 缓存,这边的先移除再添加,主要是起一个排序的作用。而 hasInstantiationAwareBeanPostProcessors 和 hasDestructionAwareBeanPostProcessors 变量用于指示 beanFactory 是否已注册过 InstantiationAwareBeanPostProcessors 和 DestructionAwareBeanPostProcessor,在之后的 容器创建过程会用到这两个变量。。。。

 

扩展使用:

 

使用方法比较简单,新建一个类实现 BeanPostProcessor 接口,并用注解将该类注册到 Spring 容器中。

 

spring源码解析(四)-registerBeanPostProcessors_第9张图片

 

这样,在 Spring 创建 bean 实例时,执行初始化方法前会调用 MyBeanPostProcessor 的 postProcessBeforeInitialization 方法,在执行初始化方法后会调用 MyBeanPostProcessor 的 postProcessAfterInitialization 方法。

spring源码解析(四)-registerBeanPostProcessors_第10张图片

可以看到 在执行这个初始化前后的方法时,我们可以取到一个入口类(这个入口类就是我自己的配置类入口MainConfig)的增强对象 是spring产生的cglib代理对象。。。(也就是说我们这个时候可以取到所有的已经实例化的对象,比如后置处理器、入口类mainconfig,也可以取到还没有实例化的bean定义和名字。。。比如person)

 

那么我们继续看这个代理对象里面的DefaultListableBeanFactory中有哪些beandefinition

spring源码解析(四)-registerBeanPostProcessors_第11张图片

 

已经实例化的bean如下:

spring源码解析(四)-registerBeanPostProcessors_第12张图片

 

 而此时因为已经到了创建bean的逻辑了(正在调用finishBeanFactoryInitialization),,,

一些后置处理器的bean早已经创建好了,,,我们这个时候可以拿到任何后置处理器的bean实例,,并且可以拿到所有我们定义的bean的beandefinition和name的信息,比如下面的person类:

spring源码解析(四)-registerBeanPostProcessors_第13张图片

 

这个时候我们就可以为所欲为了,,比如aop的后置处理器就是在这个时候生成并返回代理对象的,,以便后面在执行方法的时候实现链式调用(这里不对aop做深层次的详解,,后面的文章会单独介绍aop的源码原理。。。)

 

总结:

如同 invokeBeanFactoryPostProcessors 方法一样,registerBeanPostProcessors 方法的内容也比较少,核心过程在代码块1的注释已经写清楚、、、、

1.整个 registerBeanPostProcessors 方法围绕 BeanPostProcessor 接口展开,和 invokeBeanFactoryPostProcessors 不同的是,invokeBeanFactoryPostProcessors 方法会直接调用 BeanFactoryPostProcessor 实现类的方法,而 registerBeanPostProcessors 方法只是将 BeanPostProcessor 实现类注册到 BeanFactory 的 beanPostProcessors 缓存中。这是因为,此时还未到实例化 BeanPostProcessor 实现类的时候。

2.BeanPostProcessor 实现类调用时机  在创建 bean 实例时,执行初始化方法前后。

postProcessBeforeInitialization 方法在执行初始化方法前被调用,

postProcessAfterInitialization 方法在执行初始化方法后被调用。

3.BeanPostProcessor 实现类和 BeanFactoryPostProcessor 实现类一样,也可以通过实现 PriorityOrdered、Ordered 接口来调整自己的优先级。

4.registerBeanPostProcessors 方法和 invokeBeanFactoryPostProcessors 也会触发 bean 实例的创建(这两个方法其实都已经创建好了bean的后置处理器了,只不过BeanPostProcessor是在后面调用的,而BeanFactoryPostProcessor此时已经调用完成了

创建 Bean 实例是容器创建核心模块,,后面的文章再单独解析。。。

okay 感谢各位客官捧场,,,,夜深了   ,,,,,its time to say byebye。。。
 

 

 

你可能感兴趣的:(spring)