上一篇咱們講到spring中BeanFactoryPostProcessor能夠對bean進行修改拓展,Spring中BeanFactoryPostProcessor接口 -【Spring底層原理】,BeanDefinitionRegistryPostProcessor是BeanFactoryPostProcessor的一個子接口,那BeanDefinitionRegistryPostProcessor是否是能夠對BeanDefinitionRegistry進行修改拓展呢,答案是確定的,那什麼是BeanDefinitionRegistry呢,瞭解BeanDefinitionRegistry,首先得要知道什麼是BeanDefinitionjava
【1】BeanDefinitionspring
容器中的每個bean都會有一個對應的BeanDefinition
實例,該實例負責保存bean對象的全部必要信息,包括bean對象的class類型、是不是抽象類、構造方法和參數、其它屬性等等。數組
【2】BeanDefinitionRegistrymarkdown
BeanDefinition是定義bean的,BeanDefinitionRegistry則是bean定義信息的保存中心,也叫註冊中心,保存了bean的全部定義,之後BeanFactory就是按照BeanDefinitionRegistry裏面保存的每個bean定義信息建立bean實例。bean是單例仍是多例,bean的類型,bean的ID等信息,都是存在BeanDefinitionRegistry裏面。app
綜上,BeanDefinitionRegistryPostProcessor就是bean定義註冊中心的後置處理器,容許咱們修改拓展bean定義信息的註冊中心,在全部bean定義信息將要被加載,bean實例還未建立的時候執行oop
// 啓動測試類
@Test
public void TestMain(){
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
String[] beanNames = applicationContext.getBeanDefinitionNames();
for (String beanName : beanNames) {
System.out.println(beanName);
}
}
// 待注入的bean
public class User {
}
// BeanDefinitionRegistryPostProcessor實現類
@Component
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
System.out.println("MyBeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry");
System.out.println("bean的數量:"+ beanDefinitionRegistry.getBeanDefinitionCount());
// 經過bean的構建器生成rootbean
AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(User.class).getBeanDefinition();
beanDefinitionRegistry.registerBeanDefinition("hello",beanDefinition);
}
public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
System.out.println("MyBeanDefinitionRegistryPostProcessor#postProcessBeanFactory");
System.out.println("bean的數量:" + configurableListableBeanFactory.getBeanDefinitionCount());
}
}
// 配置類
@Configuration
@ComponentScan("postprocessor")
public class AppConfig {
}
複製代碼
能夠看到輸出結果以下,從中咱們能夠看出:源碼分析
- 先執行postProcessBeanDefinitionRegistry方法,獲取到IOC容器中bean的數量爲7
- 而後給Registry裏面註冊一個hello
- 再執行postProcessBeanFactory方法,因爲上面又註冊了一個,因此這裏獲取到IOC容器中bean的數量爲8
- 等BeanDefinitionRegistryPostProcessor裏面的方法都執行完後,再執行BeanFactoryPostProcessor裏面的方法
一樣,咱們經過Debug的方式來分析源碼,在postProcessBeanDefinitionRegistry方法處打個斷點,啓動斷點調試,根據方法調用棧來進行跟蹤:post
經過查看方法調用棧,能夠做出以下分析:測試
- 啓動IOC容器調用refresh方法
- 再依次調用invokeBeanFactoryPostProcessors()——>invokeBeanDefinitionRegistryPostProcessors()方法
- 在invokeBeanDefinitionRegistryPostProcessors方法中獲取到currentRegistryProcessors參數
public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
......
// 獲取到BeanDefinitionRegistryPostProcessor組件
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
var16 = postProcessorNames;
var9 = postProcessorNames.length;
for(var10 = 0; var10 < var9; ++var10) {
ppName = var16[var10];
if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
// 獲取currentRegistryProcessors參數
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
......
while(reiterate) {
reiterate = false;
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
String[] var19 = postProcessorNames;
var10 = postProcessorNames.length;
for(int var26 = 0; var26 < var10; ++var26) {
String ppName = var19[var26];
if (!processedBeans.contains(ppName)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
reiterate = true;
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
// 1.在這個方法裏面觸發postProcessBeanDefinnitionRegistry
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
currentRegistryProcessors.clear();
}
// 2.在這個方法裏面觸發postProcessBeanFactory方法
invokeBeanFactoryPostProcessors((Collection)registryProcessors, (ConfigurableListableBeanFactory)beanFactory);
invokeBeanFactoryPostProcessors((Collection)regularPostProcessors, (ConfigurableListableBeanFactory)beanFactory);
......
// 3.在這個方法裏面觸發postProcessorBeanFactory方法
invokeBeanFactoryPostProcessors((Collection)nonOrderedPostProcessors, (ConfigurableListableBeanFactory)beanFactory);
......
}
複製代碼
從源碼能夠看到:ui
- 先獲取BeanDefinitionRegistryPostProcessor組件
- 再按照必定規則(如優先級)加入到currentRegistryProcessors數組中
- currentRegistryProcessors做爲參數傳給invokeBeanDefinitionRegistryPostProcessors方法,最後在這個方法執行
- 下圖能夠看到此時已經將本身寫的MyBeanDefinitionRegistryPostProcessor組件給獲取到了
【1】觸發BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry
進入invokeBeanDefinitionRegistryPostProcessors方法,能夠看到,在這裏獲取到組件並觸發了postProcessBeanDefinitionRegistry:
private static void invokeBeanDefinitionRegistryPostProcessors(Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry, ApplicationStartup applicationStartup) {
Iterator var3 = postProcessors.iterator();
while(var3.hasNext()) {
BeanDefinitionRegistryPostProcessor postProcessor = (BeanDefinitionRegistryPostProcessor)var3.next();
StartupStep var10000 = applicationStartup.start("spring.context.beandef-registry.post-process");
postProcessor.getClass();
StartupStep postProcessBeanDefRegistry = var10000.tag("postProcessor", postProcessor::toString);
// 觸發postProcessBeanDefinnitionRegistry
postProcessor.postProcessBeanDefinitionRegistry(registry);
postProcessBeanDefRegistry.end();
}
}
複製代碼
【2】觸發BeanDefinitionRegistryPostProcessor組件的BeanFactoryPostProcessor#postProcessBeanFactory
在invokeBeanDefinitionRegistryPostProcessors方法執行完後,經過invokeBeanFactoryPostProcessors方法執行postProcessBeanFactory,點進源碼進行查看:
private static void invokeBeanFactoryPostProcessors(Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {
Iterator var2 = postProcessors.iterator();
while(var2.hasNext()) {
BeanFactoryPostProcessor postProcessor = (BeanFactoryPostProcessor)var2.next();
StartupStep var10000 = beanFactory.getApplicationStartup().start("spring.context.bean-factory.post-process");
postProcessor.getClass();
StartupStep postProcessBeanFactory = var10000.tag("postProcessor", postProcessor::toString);
// 執行postProcessBeanFactory
postProcessor.postProcessBeanFactory(beanFactory);
postProcessBeanFactory.end();
}
}
複製代碼
【3】觸發其餘組件的BeanFactoryPostProcessor#postProcessBeanFactory
private static void invokeBeanFactoryPostProcessors(Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {
Iterator var2 = postProcessors.iterator();
while(var2.hasNext()) {
BeanFactoryPostProcessor postProcessor = (BeanFactoryPostProcessor)var2.next();
StartupStep var10000 = beanFactory.getApplicationStartup().start("spring.context.bean-factory.post-process");
postProcessor.getClass();
StartupStep postProcessBeanFactory = var10000.tag("postProcessor", postProcessor::toString);
// 觸發postProcessorBeanFactory方法
postProcessor.postProcessBeanFactory(beanFactory);
postProcessBeanFactory.end();
}
}
複製代碼
經過源碼能夠看到的執行順序:
- 執行BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry
- 執行BeanDefinitionRegistryPostProcessor組件的BeanFactoryPostProcessor#postProcessBeanFactory
- 執行其餘組件的BeanFactoryPostProcessor#postProcessBeanFactory
AnnotationConfigApplicationContext:建立IOC對象
refresh()——>invokeBeanFactoryPostProcessors():執行BeanDefinitionRegistryPostProcessor
從容器中獲取到全部的BeanDefinitionRegistryPostProcessor組件
依次觸發全部的postProcessBeanDefinitionRegistry()方法
再來觸發postProcessorBeanFactory()方法BeanFactoryPostProcessor
再來從容器中找到BeanFactoryPostProcessor組件,而後依次觸發postProcessorBeanFactory()方法
從這個總結也能夠看出postProcessBeanDefinitionRegistry()方法要先於BeanFactoryPostProcessor()執行