日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

Spring的BeanFactoryPostProcessor接口示例代碼詳解

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

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

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

Spring的BeanFactoryPostProcessor接口示例代碼詳解

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

BeanFactoryPostProcessor 接口調用機制

BeanFactoryPostProcessor 接口的調用在 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()));}}

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

public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) { // 用于存放已經處理過的Bean名字Set<String> processedBeans = new HashSet<>(); // 一般會進入這個判斷if (beanFactory instanceof BeanDefinitionRegistry) {BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory; // 所謂的regularPostProcessors就是指實現BeanFactoryPostProcessor接口的BeanList<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>(); // 所謂的registryProcessors就是指實現BeanDefinitionRegistryPostProcessor接口的BeanList<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>(); // 這邊遍歷的是通過ApplicationContext接口注冊的BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor接口 // 需要和BeanFactory中BeanDefinitionMap中的BeanFactoryPostProcessor接口區分開for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {BeanDefinitionRegistryPostProcessor registryProcessor =(BeanDefinitionRegistryPostProcessor) postProcessor; //如果是BeanDefinitionRegistryPostProcessor,則先進行postProcessBeanDefinitionRegistry處理,這個方法一般進行BeanDefinition注冊,從這邊可以看出BeanDefinitionRegistryPostProcessor接口的方法先調用,所以優先級高于BeanFactoryPostProcessor // 通過這個代碼可以看出,通過ApplicationContext直接注冊的BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor并不支持Order接口,而是根據注冊的順序執行registryProcessor.postProcessBeanDefinitionRegistry(registry); // 保存這個BeanDefinitionRegistryPostProcessor,因為還要執行這個類的BeanFactoryPostProcessor方法;registryProcessors.add(registryProcessor);}else { // 保存,后面還要執行這個類的BeanFactoryPostProcessor方法;regularPostProcessors.add(postProcessor);}}List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>(); // 這邊獲取的是BeanFactory中的BeanDefinitionRegistryPostProcessorString[] postProcessorNames =beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);for (String ppName : postProcessorNames) { //先處理PriorityOrdered標注的BeanDefinitionRegistryPostProcessorif (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); //將其標記為已經處理,防止重復處理processedBeans.add(ppName);}} // 將其排序,以便按順序處理sortPostProcessors(currentRegistryProcessors, beanFactory); // 將其保存,以便處理這個類的BeanFactoryPostProcessor方法registryProcessors.addAll(currentRegistryProcessors); // 執行BeanDefinitionRegistryPostProcessor接口方法invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); // 清除,以便開始處理@Order標注的注解currentRegistryProcessors.clear(); // 注意:這邊重新獲取BeanDefinitionRegistryPostProcessor是有深意的,因為上面在處理@PriorityOrdered標注的BeanDefinitionRegistryPostProcessor時可能又注入了新的BeanDefinitionRegistryPostProcessor。postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);for (String ppName : postProcessorNames) { // 判斷是否處理過,防止重復處理,下面的邏輯和上面相同, 不介紹了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(); // 處理不標注注解的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();}// 調用postProcessBeanFactory 方法,所以BeanDefinitionRegistryPostProcessor中的postProcessBeanFactory方法的優先級要高。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 和普通的方式進行處理List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();List<String> orderedPostProcessorNames = new ArrayList<>();List<String> nonOrderedPostProcessorNames = new ArrayList<>();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);}} // 先執行@PriorityOrdered標注的接口sortPostProcessors(priorityOrderedPostProcessors, beanFactory);invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory); // 處理@Order標注的類List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());for (String postProcessorName : orderedPostProcessorNames) { // 這邊通過名字重新拿了Bean,應該是怕上面的處理改變了BeanorderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));}sortPostProcessors(orderedPostProcessors, beanFactory);invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);// 最后調用普通的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();}簡單總結

上面的方法看起來很長很復雜,但其實干的事情并不多,就調用了BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor接口的實現。這邊再簡單總結下具體的過程:

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

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

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

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

step3:調用BeanDefinitionRegistryPostProcessor實現的postProcessBeanFactory方法(因為BeanDefinitionRegistryPostProcessor是BeanFactoryPostProcessor的子接口)

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

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

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

到此這篇關于Spring的BeanFactoryPostProcessor接口的文章就介紹到這了,更多相關Spring BeanFactoryPostProcessor接口內容請搜索好吧啦網以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持好吧啦網!

標簽: Spring
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
日韩专区精品| av高清不卡| 亚洲欧美久久| 婷婷综合网站| 午夜国产一区二区| 午夜久久tv| 石原莉奈一区二区三区在线观看| 狠狠久久婷婷| 性一交一乱一区二区洋洋av| 青青青国产精品| 国产精品分类| 欧美亚洲一区二区三区| 欧美日韩亚洲一区二区三区在线| 日韩不卡一二三区| 国产伦精品一区二区三区千人斩| 国产精品久久久久av蜜臀| 久久香蕉精品香蕉| 国产激情在线播放| 亚洲成人国产| 国产精品呻吟| 日韩午夜视频在线| 国产伦精品一区二区三区视频| 久久久久久久久成人| 电影天堂国产精品| 99pao成人国产永久免费视频 | 国产一区二区三区黄网站| av中文资源在线资源免费观看| se01亚洲视频| 久久不射网站| 国产精品午夜av| 国产白浆在线免费观看| 欧美~级网站不卡| 中文字幕成人| 国产精品1区| 国产美女高潮在线观看| 不卡在线一区二区| 91精品国产自产在线丝袜啪| аⅴ资源天堂资源库在线| 国产亚洲高清视频| 国产精品天堂蜜av在线播放| 精品久久免费| 美女精品在线| 你懂的亚洲视频| 精品一区亚洲| 国产精品中文| av亚洲在线观看| 国产精品黄色| 99在线|亚洲一区二区| 国产精久久久| 亚洲激情中文| 麻豆精品av| 最新亚洲激情| 精品深夜福利视频| 午夜在线一区二区| 国产精品99在线观看| 欧美影院三区| 国产精品一区免费在线| 欧美日韩在线网站| 国产欧美激情| 欧美精品一区二区三区精品| 欧美偷窥清纯综合图区| 国产精品国产一区| 亚洲九九精品| 欧美sm一区| 日本午夜精品| 欧美a级一区| 久久av电影| 欧美在线综合| 日韩在线精品| 国产日产精品一区二区三区四区的观看方式 | 欧美网站在线| 精品视频在线你懂得| 丝瓜av网站精品一区二区| 精品国产91| 亚欧洲精品视频在线观看| 欧美中文字幕一区二区| 日韩精品a在线观看91| 日韩在线短视频| 日韩国产在线观看一区| 欧美影院三区| 麻豆久久久久久| 麻豆91精品| 欧美午夜精品一区二区三区电影| 国产精品一区高清| 视频一区二区三区在线| 亚洲成人二区| 麻豆精品视频在线| 亚洲欧洲专区| 黄色亚洲在线| 日韩一区三区| 国产一区一一区高清不卡| 亚欧成人精品| 快she精品国产999| av一区二区高清| 久久精品免费一区二区三区| 国产精品红桃| 日韩中文一区二区| 亚洲一区成人| 亚州av乱码久久精品蜜桃| 在线看片国产福利你懂的| 亚洲免费福利| 高清日韩欧美| 麻豆国产精品一区二区三区| 午夜在线视频一区二区区别| 激情综合自拍| 亚洲伊人av| 国产一区二区三区亚洲综合| 国产精品亚洲二区| 国产精品手机在线播放| 日韩高清在线不卡| 一区二区三区四区在线观看国产日韩 | 久久久久久夜| 另类小说一区二区三区| 国产精品免费99久久久| 四虎精品一区二区免费| 免费人成网站在线观看欧美高清| 黄色亚洲大片免费在线观看| 女同性一区二区三区人了人一| 欧美成人高清| 在线看片不卡| 亚洲中午字幕| 日韩精品一级中文字幕精品视频免费观看| 欧美日韩国产亚洲一区| 亚洲男女av一区二区| 九色精品91| 国产一区二区精品| 视频一区二区欧美| 日精品一区二区三区| 亚洲精品在线国产| 欧美一级全黄| 国产精品三级| 欧美交a欧美精品喷水| 久久99国产精品视频| 久久国产精品色av免费看| 国产精品久久777777毛茸茸| 麻豆精品视频在线观看| 国产一区二区三区四区五区传媒| 国产精品久久久久久久免费观看 | 亚洲性视频h| 午夜国产精品视频免费体验区| 99riav国产精品| 亚洲乱码久久| 日韩国产91| 国产一区一一区高清不卡| 欧洲一区二区三区精品| 国产真实久久| 免费人成网站在线观看欧美高清| 日韩一区二区三免费高清在线观看 | 国模 一区 二区 三区| 99视频+国产日韩欧美| 午夜久久av| 国产精品白丝一区二区三区| 国产一区二区精品久| 久久蜜桃av| 蜜桃视频免费观看一区| 无码日韩精品一区二区免费| 国产精品三级| 久久久久免费av| 蜜臀av性久久久久蜜臀aⅴ流畅 | 婷婷丁香综合| 亚洲1区在线观看| 精品国产午夜| 精品在线99| 日韩超碰人人爽人人做人人添| 精品一区二区三区亚洲| 欧美中文日韩| 久久亚洲资源中文字| 激情久久五月| 日韩精品一区二区三区免费视频 | 97视频热人人精品免费| 中文久久精品| 久久99青青| 黑丝一区二区| 欧美精品1区| 在线一区视频| 国产精久久久| 国产精品丝袜xxxxxxx| 欧美交a欧美精品喷水| 欧美午夜不卡| 精品亚洲a∨一区二区三区18| 性欧美69xoxoxoxo| 久久福利在线| 女主播福利一区| 国产黄色一区| 国产毛片一区| 正在播放日韩精品| 日韩激情av在线| 日韩精品久久久久久久电影99爱| 亚洲精选久久| 久久视频精品| 国产精品分类| 久久先锋影音| 精品中文字幕一区二区三区四区| 中文亚洲免费| 国产成人精品三级高清久久91| 久久香蕉精品| 深夜视频一区二区| 日韩av在线播放中文字幕| 欧美日韩激情| 97精品视频在线看|