提前了解BeanPostProcessor :https://blog.csdn.net/u014203449/article/details/86665963
BeanPostProcessor:bean后置处理器,bean创建对象初始化前后进行拦截工作的
一.BeanFactoryProcessor
现在来看看BeanFactoryProcessor:beanFactory的后置处理器;在BeanFactory标准初始化之后调用,来定制和修改BeanFactory的内容;所有的bean定义已经保存加载到beanFactory,但是bean的实例还未创建
翻译一下注释:修改容器内部bean工厂在他标出初始化之后。所有bean定义将会被加载,但是还没有bean被创建。允许重写或新添加属性甚至 早一点初始化bean。
public interface 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.
* @param beanFactory the bean factory used by the application context
* @throws org.springframework.beans.BeansException in case of errors
*/
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}
1.演示案例
@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("MyBeanFactoryPostProcessor...postProcessBeanFactory...");
int count = beanFactory.getBeanDefinitionCount();
String[] names = beanFactory.getBeanDefinitionNames();
System.out.println("当前BeanFactory中有"+count+" 个Bean");
System.out.println(Arrays.asList(names));
}
}
单元测试
@Test
public void test01(){
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(ExtConfig.class);
applicationContext.close();
}
可以获取到容器中的beanDefinition
2.原理
打个断点,看看线程执行链。
从下往上看,第一个是容器的refresh方法:
invokeBeanFactoryPostProcessors:调用BeanFactoryPostProcessors
registerBeanPostProcessors在之前看BeanPostProcessor时看过,应该熟悉。
一直点击进入PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors方法。
内容很多,但打断点的前几步看起来很熟悉,跟BeanPostProcessor一样 会按优先级划分集合再注册,这里是按优先级划分再调用方法。
再往前几步可以看到,如何寻找所有的BeanFactoryPostProcessors:
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
断点继续进入,就可以看到是如何调用的:
3.总结
BeanFactoryPostProcessor原理:
1)、ioc容器创建对象
2)、invokeBeanFactoryPostProcessors(beanFactory);
如何找到所有的BeanFactoryPostProcessor并执行他们的方法;
1)、直接在BeanFactory中找到所有类型是BeanFactoryPostProcessor的组件,并执行他们的方法
2)、在初始化创建其他组件前面执行
二.BeanDefinitionRegistryPostProcessor
翻译一下注释:
类注释:对BeanFactoryPostProcessor扩展,允许注册更多的bean定义在BeanFactoryPostProcessor之前,尤其是BeanDefinitionRegistryPostProcessor可能注册一些bean定义,这些bean定义是BeanFactoryPostProcessor的定义。
方法注释:在post-processing之前执行
/**
* Extension to the standard {@link BeanFactoryPostProcessor} SPI, allowing for
* the registration of further bean definitions <i>before</i> regular
* BeanFactoryPostProcessor detection kicks in. In particular,
* BeanDefinitionRegistryPostProcessor may register further bean definitions
* which in turn define BeanFactoryPostProcessor instances.
*
* @author Juergen Hoeller
* @since 3.0.1
* @see org.springframework.context.annotation.ConfigurationClassPostProcessor
*/
public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {
/**
* 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.
* @param registry the bean definition registry used by the application context
* @throws org.springframework.beans.BeansException in case of errors
*/
void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;
}
1.演示案例
因为BeanDefinitionRegistryPostProcessor继承BeanFactoryPostProcessor,有两个方法postProcessBeanDefinitionRegistry和postProcessBeanFactory。
在postProcessBeanDefinitionRegistr中我们新增一个BeanDefition,新增BeanDefition有两个方法:
- RootBeanDefinition beanDefinition = new RootBeanDefinition(Blue.class);
- AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(Blue.class).getBeanDefinition();
然后用registry注册进入。
在postProcessBeanFactory把beanDefinition的个数打印,运行后会发现 beanFactory中的bean定义多了一个
@Component
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor{
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
// TODO Auto-generated method stub
System.out.println("MyBeanDefinitionRegistryPostProcessor...bean的数量:"+beanFactory.getBeanDefinitionCount());
}
//BeanDefinitionRegistry Bean定义信息的保存中心,以后BeanFactory就是按照BeanDefinitionRegistry里面保存的每一个bean定义信息创建bean实例;
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
// TODO Auto-generated method stub
System.out.println("postProcessBeanDefinitionRegistry...bean的数量:"+registry.getBeanDefinitionCount());
//RootBeanDefinition beanDefinition = new RootBeanDefinition(Blue.class);
AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(Blue.class).getBeanDefinition();
registry.registerBeanDefinition("hello", beanDefinition);
}
}
单元测试
@Test
public void test01(){
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(ExtConfig.class);
applicationContext.close();
}
运行结果:
2.原理
断点打在MyBeanDefinitionRegistryPostProcessor的两个方法上,看执行流程
和BeanFactoryPostProcessor的执行流程一样,refresh 的 invokeBeanFactoryPostProcessors
断点进入到PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors方法,这个方法BeanFactoryPostProcessor也执行过:
很明显,执行流程是
BeanDefinitionRegistryPostProcessor.postProcessBeanDefinitionRegistry
---->BeanDefinitionRegistryPostProcessor.postProcessBeanFactory
----->BeanFactoryPostProcessor.postProcessBeanFactory
调用的方法也很简单,获取所有的BeanDefinitionRegistryPostProcessor然后循环调用
3.总结
原理:
1)、ioc创建对象
2)、refresh()-》invokeBeanFactoryPostProcessors(beanFactory);
3)、从容器中获取到所有的BeanDefinitionRegistryPostProcessor组件。
1、依次触发所有的postProcessBeanDefinitionRegistry()方法
2、再来触发postProcessBeanFactory()方法
4)、再来从容器中找到BeanFactoryPostProcessor组件;然后依次触发postProcessBeanFactory()方法