閱讀源碼有利於陶冶情操,承接前文Spring源碼情操陶冶-AbstractApplicationContext#postProcessBeanFactory
約定:web.xml中配置的contextClass
為XmlWebApplicationContext
瞧瞧官方注釋
/**
* Instantiate and invoke all registered BeanFactoryPostProcessor beans,
* respecting explicit order if given.
* <p>Must be called before singleton instantiation.必須在單例實例化前調用
*/
主要是實例化和調用所有已注冊的BeanFactoryPostProcessors beans
源碼簡析
對應的代碼清單如下
//通過一個委托類來處理實例化調用
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
}
PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors
簡單的看下委托類中的此方法源碼,代碼清單如下
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
// 第一步,Invoke BeanDefinitionRegistryPostProcessors first, if any.
Set<String> processedBeans = new HashSet<String>();
//條件滿足
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<BeanFactoryPostProcessor>();
List<BeanDefinitionRegistryPostProcessor> registryPostProcessors =
new LinkedList<BeanDefinitionRegistryPostProcessor>();
//剛開始進來beanFactoryPostProcessors為空
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
//BeanDefinitionRegistryPostProcessor目前該接口的實現者為MapperScannerConfigurer/ConfigurationClassPostProcessor
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryPostProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
//調用postProcessBeanDefinitionRegistry接口,比如MapperScannerConfigurer則會進行掃描注冊接口bean操作
registryPostProcessor.postProcessBeanDefinitionRegistry(registry);
registryPostProcessors.add(registryPostProcessor);
}
else {
regularPostProcessors.add(postProcessor);
}
}
// 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.
//尋找實現了BeanDefinitionRegistryPostProcessor接口類的beans
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.這里只有ConfigurationClassPostProcessor類才操作
List<BeanDefinitionRegistryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
***
省略部分代碼
***
// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
invokeBeanFactoryPostProcessors(registryPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
}
else {
// Invoke factory processors registered with the context instance.
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}
//第二步,處理注冊在bean工廠中BeanFactoryPostProcessor接口實現類並調用公用的方法,比如PropertyResourceConfigurer資源文件解析類
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
// Ordered, and the rest. 執行的優先權
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
List<String> orderedPostProcessorNames = new ArrayList<String>();
List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
for (String ppName : postProcessorNames) {
if (processedBeans.contains(ppName)) {
// skip - already processed in first phase above
}
else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
else {
nonOrderedPostProcessorNames.add(ppName);
}
}
***
省略部分代碼
***
}
主要功能是對實現BeanFactoryPostProcessor的bean類進行調用公共接口方法postProcessBeanFactory
,並相關的信息可關聯至ConfigurableListableBeanFactory
beanFactory。常見的使用類為PropertyPlaceholderConfigurer文件解析類、MapperScannerConfigurer SQL接口注冊類。公共接口的調用前者會對每個bean對象含有${}
進行解析替換,后者會注冊mapper class接口類並嘗試解析注解
下節預告
Spring源碼情操陶冶-AbstractApplicationContext#registerBeanPostProcessors