Spring IOC(6)BeanFactoryPostProcessor(3)摻雜@MapperScan原理分析

學習儀式感發表於2020-11-01

繼承BeanDefinitionRegistryPostProcessor 方法後需要執行postProcessBeanDefinitionRegistry和
postProcessBeanFactory方法
public class YdBeanFactoryPostprocessor implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
}

@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
}
}


{
AnnotationConfigApplicationContext applicationContext=new AnnotationConfigApplicationContext();
applicationContext.register(JavaConfig.class);
applicationContext.addBeanFactoryPostProcessor(new YdBeanFactoryPostprocessor());
//api提供的首先執行
//很少有人這麼做,在掃描之前新增後置處理器,應該是根本沒有才對
applicationContext.refresh();
}


在spring原始碼中:
//百分之90的beanFactory都是BeanDefinitionRegistry,基本上不存在,我們忽略%10
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
List regularPostProcessors = new ArrayList<>();
//標準的後置處理器,spring呼叫invokeBeanFactoryPostProcessors傳list過來,可能有值,可能沒值
//有兩種情況,1、沒有元素;—90%;2,有元素----10%
//存放所有的BeanDefinitionRegistryPostProcessor
//存放所有內建的BeanFactoryPostProcessor
List registryProcessors = new ArrayList<>();
//只有兩種型別,一種父類,一種是子類
//BeanDefinitionRegistryPostProcessor,
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
//做一次強轉
registryProcessor.postProcessBeanDefinitionRegistry(registry);
registryProcessors.add(registryProcessor);
}
else {
regularPostProcessors.add(postProcessor);
}
}
父類:BeanFactoryPostProcessor
子類:BeanDefinitionRegistryPostProcessor
然後根據PriorityOrdered,order,無等去排序執行invokeBeanDefinitionRegistryPostProcessors方法;
以上都在執行子類裡的方法postProcessBeanDefinitionRegistry,而沒有執行父類的postProcessBeanFactory方法;
父類的方法統一在後面的兩行程式碼中執行;
在這兩行程式碼中執行了,api提供的,和內建的BeanDefinition的父類的postProcessBeanFactory方法;
其中:
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
//該方法只執行既實現子類,又實現父類的postProcessBeanFactory方法;(只包括三種,api提供和內建的,還有程式設計師提供的也在這裡執行)
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
(和上面那個方法不同只包括兩種api提供或者內建)
//該方法只執行的直接實現父類,沒有實現子類的postProcessBeanFactory方法;
再往下又繼續根據PriorityOrdered,order,無等方法排序的程式設計師自己通過程式碼實現,然後非api插入spring中,而是通過註解加入到spring容器中的只實現了BeanFactoryPostProcessor的方法的進行排序執行;
mybaits
當我們spring執行完
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);方法的時候
會去執行
@MapperScan(“sum.mapper”)–》@Import(MapperScannerRegistrar.class)–》MapperScannerRegistrar種的registerBeanDefinitions方法;
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
AnnotationAttributes mapperScanAttrs = AnnotationAttributes
.fromMap(importingClassMetadata.getAnnotationAttributes(MapperScan.class.getName()));
if (mapperScanAttrs != null) {
//判斷@MapperScan(“sum.mapper”)是否寫了包名
registerBeanDefinitions(mapperScanAttrs, registry);
}
}

執行內建的BeanDefinitionRegistryPostProcessor
老版的mybatis
從 registerBeanDefinitions(mapperScanAttrs, registry);方法就開始掃描與我們mybatis相關的類,符合規則的,加入到容器中,讓spring自己去例項化bean;

新版的mybatis
基本上什麼事都沒做,只是把一個MapperScannerConfigurer(一個BeanDefinition)屬於BeanDefinitionRegistryPostProcessor型別的;這個類沒有實現order,屬於第三種情況,普通的BeanDefinitionRegistryPostProcessor;但是掃描方法還是寫在mybaits中,只是執行時機改變了;

相關文章