国产成人精品久久免费动漫-国产成人精品天堂-国产成人精品区在线观看-国产成人精品日本-a级毛片无码免费真人-a级毛片毛片免费观看久潮喷

您的位置:首頁技術(shù)文章
文章詳情頁

Spring的BeanFactoryPostProcessor接口示例代碼詳解

瀏覽:9日期:2023-07-22 09:13:37
接口簡介

BeanFactoryPostProcessor 接口是 Spring 初始化 BeanFactory 時對外暴露的擴(kuò)展點(diǎn),Spring IoC 容器允許 BeanFactoryPostProcessor 在容器實(shí)例化任何 bean 之前讀取 bean 的定義,并可以修改它。

BeanDefinitionRegistryPostProcessor 繼承自 BeanFactoryPostProcessor,比 BeanFactoryPostProcessor 具有更高的優(yōu)先級,主要用來在常規(guī)的 BeanFactoryPostProcessor 檢測開始之前注冊其他 bean 定義。特別是,你可以通過 BeanDefinitionRegistryPostProcessor 來注冊一些常規(guī)的 BeanFactoryPostProcessor,因為此時所有常規(guī)的 BeanFactoryPostProcessor 都還沒開始被處理。

Spring的BeanFactoryPostProcessor接口示例代碼詳解

注意點(diǎn):通過BeanDefinitionRegistryPostProcessor 注冊的 BeanDefinitionRegistryPostProcessor 接口的postProcessBeanDefinitionRegistry方法將得不到調(diào)用,具體的原因會在下面的代碼中解釋。

BeanFactoryPostProcessor 接口調(diào)用機(jī)制

BeanFactoryPostProcessor 接口的調(diào)用在 AbstractApplicationContext#invokeBeanFactoryPostProcessors方法中。

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime// (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));}}

進(jìn)入PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors())方法:

public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) { // 用于存放已經(jīng)處理過的Bean名字Set<String> processedBeans = new HashSet<>(); // 一般會進(jìn)入這個判斷if (beanFactory instanceof BeanDefinitionRegistry) {BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory; // 所謂的regularPostProcessors就是指實(shí)現(xiàn)BeanFactoryPostProcessor接口的BeanList<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>(); // 所謂的registryProcessors就是指實(shí)現(xiàn)BeanDefinitionRegistryPostProcessor接口的BeanList<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>(); // 這邊遍歷的是通過ApplicationContext接口注冊的BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor接口 // 需要和BeanFactory中BeanDefinitionMap中的BeanFactoryPostProcessor接口區(qū)分開for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {BeanDefinitionRegistryPostProcessor registryProcessor =(BeanDefinitionRegistryPostProcessor) postProcessor; //如果是BeanDefinitionRegistryPostProcessor,則先進(jìn)行postProcessBeanDefinitionRegistry處理,這個方法一般進(jìn)行BeanDefinition注冊,從這邊可以看出BeanDefinitionRegistryPostProcessor接口的方法先調(diào)用,所以優(yōu)先級高于BeanFactoryPostProcessor // 通過這個代碼可以看出,通過ApplicationContext直接注冊的BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor并不支持Order接口,而是根據(jù)注冊的順序執(zhí)行registryProcessor.postProcessBeanDefinitionRegistry(registry); // 保存這個BeanDefinitionRegistryPostProcessor,因為還要執(zhí)行這個類的BeanFactoryPostProcessor方法;registryProcessors.add(registryProcessor);}else { // 保存,后面還要執(zhí)行這個類的BeanFactoryPostProcessor方法;regularPostProcessors.add(postProcessor);}}List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>(); // 這邊獲取的是BeanFactory中的BeanDefinitionRegistryPostProcessorString[] postProcessorNames =beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);for (String ppName : postProcessorNames) { //先處理PriorityOrdered標(biāo)注的BeanDefinitionRegistryPostProcessorif (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); //將其標(biāo)記為已經(jīng)處理,防止重復(fù)處理processedBeans.add(ppName);}} // 將其排序,以便按順序處理sortPostProcessors(currentRegistryProcessors, beanFactory); // 將其保存,以便處理這個類的BeanFactoryPostProcessor方法registryProcessors.addAll(currentRegistryProcessors); // 執(zhí)行BeanDefinitionRegistryPostProcessor接口方法invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); // 清除,以便開始處理@Order標(biāo)注的注解currentRegistryProcessors.clear(); // 注意:這邊重新獲取BeanDefinitionRegistryPostProcessor是有深意的,因為上面在處理@PriorityOrdered標(biāo)注的BeanDefinitionRegistryPostProcessor時可能又注入了新的BeanDefinitionRegistryPostProcessor。postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);for (String ppName : postProcessorNames) { // 判斷是否處理過,防止重復(fù)處理,下面的邏輯和上面相同, 不介紹了if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));processedBeans.add(ppName);}}sortPostProcessors(currentRegistryProcessors, beanFactory);registryProcessors.addAll(currentRegistryProcessors);invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);currentRegistryProcessors.clear(); // 處理不標(biāo)注注解的BeanDefinitionRegistryPostProcessorboolean reiterate = true;while (reiterate) {reiterate = false;postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);for (String ppName : postProcessorNames) {if (!processedBeans.contains(ppName)) {currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));processedBeans.add(ppName);reiterate = true;}}sortPostProcessors(currentRegistryProcessors, beanFactory);registryProcessors.addAll(currentRegistryProcessors);invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);currentRegistryProcessors.clear();}// 調(diào)用postProcessBeanFactory 方法,所以BeanDefinitionRegistryPostProcessor中的postProcessBeanFactory方法的優(yōu)先級要高。invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);}else {// Invoke factory processors registered with the context instance.invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);}// 開始處理BeanFactoryPostProcessor接口String[] postProcessorNames =beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);// 也是按照@PriorityOrdered @Ordered 和普通的方式進(jìn)行處理List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();List<String> orderedPostProcessorNames = new ArrayList<>();List<String> nonOrderedPostProcessorNames = new ArrayList<>();for (String ppName : postProcessorNames) { // 可能已經(jīng)處理過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);}} // 先執(zhí)行@PriorityOrdered標(biāo)注的接口sortPostProcessors(priorityOrderedPostProcessors, beanFactory);invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory); // 處理@Order標(biāo)注的類List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());for (String postProcessorName : orderedPostProcessorNames) { // 這邊通過名字重新拿了Bean,應(yīng)該是怕上面的處理改變了BeanorderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));}sortPostProcessors(orderedPostProcessors, beanFactory);invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);// 最后調(diào)用普通的BeanFactoryPostProcessorList<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());for (String postProcessorName : nonOrderedPostProcessorNames) {nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));}invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);// Clear cached merged bean definitions since the post-processors might have// modified the original metadata, e.g. replacing placeholders in values...beanFactory.clearMetadataCache();}簡單總結(jié)

上面的方法看起來很長很復(fù)雜,但其實(shí)干的事情并不多,就調(diào)用了BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor接口的實(shí)現(xiàn)。這邊再簡單總結(jié)下具體的過程:

step1:執(zhí)行通過ApplicationContext#addBeanFactoryPostProcessor()方法注冊的BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor。

具體過程如下:假如通過ApplicationContext注冊了一個BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor,那么會先執(zhí)行BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法,但是BeanDefinitionRegistryPostProcessor的postProcessBeanFactory方法和BeanFactoryPostProcessor的postProcessBeanFactory方法暫時都不會在這步執(zhí)行。

另外需要注意的是:通過ApplicationContext注冊的BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor都不支持@PriorityOrdered和@Ordered順序處理,而是按照我們添加的順序處理

step2:處理BeanFactory中的BeanDefinitionRegistryPostProcessor,處理的順序是先處理@PriorityOrdered標(biāo)注的,再處理@Ordered標(biāo)注的,最后處理普通的BeanDefinitionRegistryPostProcessor。到這邊,所有BeanDefinitionRegistryPostProcessor接口的postProcessBeanDefinitionRegistry方法都已經(jīng)調(diào)用完畢,下面就開始處理BeanFactoryPostProcessor的postProcessBeanFactory方法。

step3:調(diào)用BeanDefinitionRegistryPostProcessor實(shí)現(xiàn)的postProcessBeanFactory方法(因為BeanDefinitionRegistryPostProcessor是BeanFactoryPostProcessor的子接口)

step4:調(diào)用通過ApplicationContext#addBeanFactoryPostProcessor()注冊的“單純”的BeanFactoryPostProcessor

step5:調(diào)用BeanFactory中的BeanFactoryPostProcessor,調(diào)用順序也是按照@PriorityOrdered和@Ordered順序處理,沒有這兩個注解的最后處理。

好了,到這邊BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor接口就已經(jīng)處理完了。后面我們會拿ConfigurationClassPostProcessor 這個特殊的BeanDefinitionRegistryPostProcessor做列子講下具體流程,這邊只是介紹BeanFactoryPostProcessor的調(diào)用機(jī)制。

到此這篇關(guān)于Spring的BeanFactoryPostProcessor接口的文章就介紹到這了,更多相關(guān)Spring BeanFactoryPostProcessor接口內(nèi)容請搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持好吧啦網(wǎng)!

標(biāo)簽: Spring
相關(guān)文章:
主站蜘蛛池模板: 在线成人a毛片免费播放 | 国产v欧美v日韩在线观看 | 三级国产精品一区二区 | 男女配种猛烈免费视频 | 免费99热在线观看 | 午夜在线观看视频免费 成人 | 一级绝黄| 亚洲国产精品第一区二区三区 | 国产成人精品高清在线观看99 | 一级毛片日韩a欧美 | 亚洲国产欧美另类 | 久久er精品视频 | 97国产精品欧美一区二区三区 | 精品国产一区在线观看 | 成人免费黄色网址 | 99久久国产免费 - 99久久国产免费 | 日本久久99 | 久久成人免费播放网站 | 亚欧成人毛片一区二区三区四区 | 日韩啪| 亚洲成a人片在线观 | 91网在线 | 一级a级国产不卡毛片 | 人成18亚洲资源在线 | 成人免费视频69 | xxxwww黄色 | 国产日韩高清一区二区三区 | 偶偶福利影院 | 男人天堂手机在线 | 成在线人视频免费视频 | 国产99久久九九精品免费 | 久久香焦| 男女性关系视频免费观看软件 | 一级做人爱a视频正版免费 一级做性色a爱片久久片 | 成人免费国产欧美日韩你懂的 | 欧美在线精品一区二区三区 | 国内精品久久久久久久影视麻豆 | 97视频免费播放观看在线视频 | 精品国产欧美一区二区五十路 | 日韩午夜在线观看 | 亚洲成a人片在线观看 欧美 |