上节我们介绍了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),
单击该行代码跳转到具体的实现
1.注册 BeanPostProcessor,见代码块1详解。
5.1 对 priorityOrderedPostProcessors进行排序,,在invokeBeanFactoryPostProcessors文章中 代码中3已经解析过。
5.2 注册 priorityOrderedPostProcessors,见代码块2详解。
2.将 PostProcessor 添加到 BeanFactory 中的 beanPostProcessors 缓存,见代码块3详解。
该方法作用就是将 BeanPostProcessor 添加到 beanPostProcessors 缓存,这边的先移除再添加,主要是起一个排序的作用。而 hasInstantiationAwareBeanPostProcessors 和 hasDestructionAwareBeanPostProcessors 变量用于指示 beanFactory 是否已注册过 InstantiationAwareBeanPostProcessors 和 DestructionAwareBeanPostProcessor,在之后的 容器创建过程会用到这两个变量。。。。
使用方法比较简单,新建一个类实现 BeanPostProcessor 接口,并用注解将该类注册到 Spring 容器中。
这样,在 Spring 创建 bean 实例时,执行初始化方法前会调用 MyBeanPostProcessor 的 postProcessBeforeInitialization 方法,在执行初始化方法后会调用 MyBeanPostProcessor 的 postProcessAfterInitialization 方法。
可以看到 在执行这个初始化前后的方法时,我们可以取到一个入口类(这个入口类就是我自己的配置类入口MainConfig)的增强对象 是spring产生的cglib代理对象。。。(也就是说我们这个时候可以取到所有的已经实例化的对象,比如后置处理器、入口类mainconfig,也可以取到还没有实例化的bean定义和名字。。。比如person)
那么我们继续看这个代理对象里面的DefaultListableBeanFactory中有哪些beandefinition
已经实例化的bean如下:
而此时因为已经到了创建bean的逻辑了(正在调用finishBeanFactoryInitialization),,,
一些后置处理器的bean早已经创建好了,,,我们这个时候可以拿到任何后置处理器的bean实例,,并且可以拿到所有我们定义的bean的beandefinition和name的信息,比如下面的person类:
这个时候我们就可以为所欲为了,,比如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。。。