1、首先看自定义的BeanFactoryPostProcessor/BeanDefinitionRegistryPostProcessor执行链路【都是一样的他们】
1)、BeanDefinitionRegistryPostProcessor执行时在BeanFactoryPostProcessor之前
2)、PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors方法里面完成的
- BeanDefinitionRegistryPostProcessor的执行顺序优先于BeanFactoryPostProcessor
2、调用流程
BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessor都是在这里被处理的流程一模一样
AnnotationConfigApplicationContext
--》初始化方法(构造函数)
--》refresh
--》invokeBeanFactoryPostProcessors(beanFactory)调用BeanFactoryPostProcessor
--》PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors())
PostProcessorRegistrationDelegate类中的方法
--》invokeBeanFactoryPostProcessors内部执行逻辑
1)、在beanFactory中查找BeanDefinitionRegistryPostProcessor.class类型的bean定义,找出来【得到一个List】
1)、拿到List集合调用了beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class/BeanFactoryPostProcessor)【完成了bean的实例化动作】
2)、看看是否实现了PriorityOrdered接口(优先级较高的排序)beanFactory.isTypeMatch(ppName, PriorityOrdered.class)【筛选后的List01】
3)、看看是否实现了Ordered接口(排序低于PriorityOrdered) beanFactory.isTypeMatch(ppName, Ordered.class)【筛选后的List02】
4)、剩下的就是普通的BeanFactoryPostProcessor,没有实现任何排序接口的【筛选后的List03】
3)、invokeBeanDefinitionRegistryPostProcessors调用【筛选后的List01--03】分别各自调用这个接口(List为输入参数)
1)、拿到上面List参数循环,由于List里面就是具体
2)、BeanDefinitionRegistryPostProcessor--调用这个方法postProcessBeanDefinitionRegistry(registry)//参数其实就是beanFactory
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory,只是通过这种方式转化了一下而已
3)、BeanFactoryPostProcessor--调用这个方法postProcessBeanFactory(beanFactory)
到这里就实现了对MyBeanFactoryPostProcessor自定义BeanFactoryPostProcessor方法postProcessBeanFactory进行调用
3、自定义的BeanFactoryPostProcessor
MyBeanFactoryPostProcessor
//一定要定义为组件,让spring容器加载,否则spring容器就无法识别
@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
/**
* Modify the application context's internal bean factory after its standard
* initialization. All bean definitions will have been loaded, but no beans
* will have been instantiated yet. This allows for overriding or adding
* properties even to eager-initializing beans.
* 翻译:
* 在应用程序spring上下文内部的bean工厂完成初始化以后提供其修改功能
* 所有的bean定义都已经加载完毕,但是这些bean都还被实例化。这个时候允许重新覆盖(原来已加载的bean定义)
* 或者甚至可以给bean定义添加属性
* @param beanFactory the bean factory used by the application context
* @throws org.springframework.beans.BeansException in case of errors
*/
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("MyBeanFactoryPostProcessor--postProcessBeanFactory");
/**
* 1、把已经定义的beanName找出来,把对应的beanClass进行替换
* 如下把wolfBean已经定义的WolfBean.class修改成SunBean.class
*/
RootBeanDefinition beanDefinition = (RootBeanDefinition) beanFactory.getBeanDefinition("wolfBean");
beanDefinition.setBeanClass(SunBean.class);
/**
* 2、给beanFactory容器注册一个单例bean,名称和Object
*/
beanFactory.registerSingleton("god",new Dog()); //通过反射的方式实例化
}
}
6、自定义BeanDefinitionRegistryPostProcessor
@Component
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
/**
* Modify the application context's internal bean definition registry after its
* standard initialization. All regular bean definitions will have been loaded,
* but no beans will have been instantiated yet. This allows for adding further
* bean definitions before the next post-processing phase kicks in.
* 翻译:
* 1、允许修改spring容器里面的bean定义,在标准初始化之后;所有合法的bean定义将要被加载,
* 但是没有Bean被实例化。这允许我们
* 他的意见允许进一步增加
* <p>
* 在下一个后期处理阶段开始之前定义bean
*
* @param registry the bean definition registry used by the application context
* @throws org.springframework.beans.BeansException in case of errors
*/
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
System.out.println("MyBeanDefinitionRegistryPostProcessor---postProcessBeanDefinitionRegistry");
int count = registry.getBeanDefinitionCount();
System.out.println("bean 定义数量为" + count);
String[] beanDefinitionNames = registry.getBeanDefinitionNames();
for (String name : beanDefinitionNames) {
System.out.println(name);
}
RootBeanDefinition beanDefinition = new RootBeanDefinition();
beanDefinition.setBeanClass(PersonDao.class);
registry.registerBeanDefinition("PersonDao", beanDefinition);
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
}
}
5、执行类
@Configuration//定义为配置类
@ComponentScan("com.extend")//扫描加上,不然组件等信息就无法被spring容器加载
public class MyBeanFactoryPostProcessorTest{
/**
* 扩展原理分析参考
* BeanPostProcessor bean的后置处理器
* 1、在bean创建对象初始化之前和之后执行相关业务,以实现对bean的增强
* BeanFactoryPostProcessor beanFactory的后置处理器
* 2、BeanDefinitionRegistryPostProcessor bean定义注册后置处理器
*
* 1、在beanFactory初始化之后进行调用,这样可以实现对beanFactory里面定义的beanDefinition修改和扩展
* 这个时候所有的bean定义都被加载完毕,但是bean还没有创建
* 2、BeanFactoryPostProcessor实现原理
* 先断点到自定义的BeanFactoryPostProcessor,看看代码执行链路
* 1)、
* @param args
*/
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyBeanFactoryPostProcessorTest.class);
System.out.println(JSON.toJSONString(context.getBeanDefinitionNames()));
}
@Bean
WolfBean wolfBean(){
return new WolfBean();
}
}
后记
先看看DefaultListableBeanFactory类图结构
Spring容器及其他第三方开源框架基于这个的实现
- BeanDefinitionRegistryPostProcessor
- BeanFactoryPostProcessor