备战360第二天
本文目的是了解BeanDefinition准备好之后 的 后续一些工作,可以通过提供的自定义埋点,可以定制化一些内容。
主要还是进入refresh代码进行调试查看
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
...
// 为上下文注册BeanFactory后置处理器.
invokeBeanFactoryPostProcessors(beanFactory);
...
}
实例化并调用所有注册的BeanFactory后置处理器,并进行排序,顺序可以显示设置
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
//相关后置处理器逻辑
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
...
}
扫描自定义实现BeanDefinitionRegistryPostProcessor并进行sort之后执行
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean factory post-processors apply to them!
// Separate between BeanDefinitionRegistryPostProcessors that implement
// PriorityOrdered, Ordered, and the rest.
//
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
//首先,加载实现BeanDefinitionRegistryPostProcessor接口的所有类
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
//进行排序,如果实现了PriorityOrdered接口,可以进行实现相应方法动态决定加载顺序
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
//真正执行注册的这些后置处理器
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
currentRegistryProcessors.clear();
...
}
这里提供两个测试类,来验证排序和一般实战内容
BeanDefinitionRegistryPostProcessorTest
public class BeanDefinitionRegistryPostProcessorTest implements BeanDefinitionRegistryPostProcessor, PriorityOrdered {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
//这里Test只有一个有参构造,所以进行对应参数构造BeanDefinition
GenericBeanDefinition genericBeanDefinition = new GenericBeanDefinition();
genericBeanDefinition.setBeanClass(Test.class);
ConstructorArgumentValues constructorArgumentValues = new ConstructorArgumentValues();
constructorArgumentValues.addGenericArgumentValue("333");
genericBeanDefinition.setConstructorArgumentValues(constructorArgumentValues);
registry.registerBeanDefinition("sss",genericBeanDefinition);
System.out.println("BeanDefinitionRegistryPostProcessorTest start");
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
}
@Override
public int getOrder() {
return 9;
}
}
BeanDefinitionRegistryPostProcessorTest1
public class BeanDefinitionRegistryPostProcessorTest1 implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
System.out.println("BeanDefinitionRegistryPostProcessorTest1 start");
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
}
// @Override
// public int getOrder() {
// return 2;
// }
}
测试结果
开始DemoApplication#0
开始test
开始com.example.demo.Test1#0
开始com.example.demo.ApplicationListenerTest#0
开始com.example.demo.BeanDefinitionRegistryPostProcessorTest#0
开始com.example.demo.BeanDefinitionRegistryPostProcessorTest1#0
BeanDefinitionRegistryPostProcessorTest start
如果上述BeanDefinitionRegistryPostProcessorTest1 也实现了PriorityOrdered 接口,并且实现方法返回值越小,越先执行。
小结:
此文是了解BeanDefinition注册Map之后的后置处理,了解之后可以通过自定义后置处理器,处理一些自定义的bean定义信息,或者按照自定义顺序执行自定义后置处理器。
为什么要了解这块源码,首先知道有这么个东西,有业务需求的时候可以用上,并且了解源码之后,当你需要使用时,可以通过ClassPathXmlApplicationContext这个类查看对应流程,定位到是实现哪个接口,实现哪些定制化流程,减少了百度的过程。