偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

Spring 中如何控制 Bean 的加載順序?

開發(fā) 前端
@DependsOn 是 Spring 框架提供的一個(gè)注解,用于指示 Spring 容器在初始化一個(gè) Bean 之前,必須先初始化其依賴的其他 Bean。這個(gè)注解可以幫助解決 Bean 間的依賴關(guān)系,確保依賴的 Bean 已經(jīng)準(zhǔn)備就緒。

如果你脫口而出說(shuō)添加 @Order 注解或者是實(shí)現(xiàn) Ordered 接口,那么恭喜,你掉坑了。

一、@Order 注解和 Ordered 接口

在 Spring 框架中,@Order 是一個(gè)非常實(shí)用的元注解,它位于 spring-core 包下,主要用于控制某些特定上下文中組件的執(zhí)行順序或排序,但它并不直接控制 Bean 的初始化順序。

1.1 用途

@Order 注解或者是 Ordered 接口,常見的用途主要是兩種:

  • 定義執(zhí)行順序:當(dāng)多個(gè)組件(如攔截器、過(guò)濾器、監(jiān)聽器等)需要按照特定的順序執(zhí)行時(shí),@Order 注解可以用來(lái)指定這些組件的執(zhí)行優(yōu)先級(jí)。數(shù)值越小,優(yōu)先級(jí)越高,相應(yīng)的組件會(huì)更早被執(zhí)行或被放置在集合的前面(@Order 注解接受一個(gè)整數(shù)值,這個(gè)值可以是負(fù)數(shù)、零或正數(shù)。Spring 框架提供了 Ordered.HIGHEST_PRECEDENCE(默認(rèn)最低優(yōu)先級(jí))和 Ordered.LOWEST_PRECEDENCE(默認(rèn)最高優(yōu)先級(jí))常量,分別對(duì)應(yīng)于  Integer.MIN_VALUE和 Integer.MAX_VALUE,可以方便地設(shè)定優(yōu)先級(jí)。)。
  • 集合排序:當(dāng)相同類型的組件被自動(dòng)裝配到一個(gè)集合中時(shí),@Order 注解會(huì)影響它們?cè)谶@個(gè)集合中的排列順序。

1.2 使用場(chǎng)景

經(jīng)典使用場(chǎng)景。

攔截器排序

在 Spring MVC 中,可以使用 @Order 來(lái)控制攔截器的執(zhí)行順序。

Spring Security Filters(過(guò)濾器)

在 Spring Security 中,過(guò)濾器鏈的順序通過(guò) @Order 來(lái)定義,確保正確的安全處理流程。這個(gè)在松哥最近的教程中和大家詳細(xì)介紹過(guò)了。

圖片圖片

Event Listeners(事件監(jiān)聽器)

當(dāng)有多個(gè)監(jiān)聽同一事件的監(jiān)聽器時(shí),可以通過(guò) @Order 來(lái)控制它們的觸發(fā)順序。

Bean 的集合注入

當(dāng)一個(gè) Bean 依賴于一個(gè)特定類型的 Bean 集合時(shí),帶有 @Order 注解的 Bean 將按照指定順序被注入。

可以看到,@Order 注解的使用場(chǎng)景中,主要是相同類型的 Bean 存在多個(gè)時(shí),這多個(gè) Bean 的執(zhí)行順序可以通過(guò) @Order 注解或者實(shí)現(xiàn) Ordered 接口來(lái)確定。

但是?。?!

@Order 注解不控制初始化和加載:@Order 注解不直接影響 Bean 的創(chuàng)建和初始化過(guò)程,這些由 Spring IoC 容器基于依賴關(guān)系和配置來(lái)決定。Spring IoC 容器根據(jù)依賴關(guān)系圖來(lái)決定 Bean 的初始化順序,而不是依據(jù) @Order 注解。依賴關(guān)系決定了哪些 Bean 需要在其他 Bean 初始化之前被創(chuàng)建。

二、如何設(shè)置 Bean 的加載順序?

有兩種方式來(lái)設(shè)置 Bean 的加載順序。

2.1 @DependsOn

@DependsOn 是 Spring 框架提供的一個(gè)注解,用于指示 Spring 容器在初始化一個(gè) Bean 之前,必須先初始化其依賴的其他 Bean。這個(gè)注解可以幫助解決 Bean 間的依賴關(guān)系,確保依賴的 Bean 已經(jīng)準(zhǔn)備就緒。

@DependsOn 可以放在任何一個(gè) Spring 管理的 Bean 定義上,包括但不限于配置類、服務(wù)類、數(shù)據(jù)訪問(wèn)對(duì)象等。其語(yǔ)法如下:

@DependsOn({"beanName1", "beanName2", ...})
public class MyBean {
    // ...
}

在這個(gè)例子中,MyBean 類聲明了它依賴于名為 beanName1 和 beanName2 的 Bean。這意味著,當(dāng) Spring 容器創(chuàng)建 MyBean 的實(shí)例時(shí),它會(huì)首先確保 beanName1 和 beanName2 已經(jīng)被正確初始化。

相關(guān)的源碼在 AbstractBeanFactory#doGetBean 方法中:

圖片圖片

在創(chuàng)建的 Bean 的時(shí)候,先檢查該 Bean 是否依賴了其他 Bean,如果依賴了,則先把其他 Bean 創(chuàng)建出來(lái),然后再繼續(xù)創(chuàng)建當(dāng)前 Bean,這樣就確保了 Bean 的加載順序。

如果小伙伴們對(duì)這塊的完整流程感興趣,可以看松哥錄制的 Spring源碼分析。

2.2 BeanFactoryPostProcessor

第二種方式就是利用 BeanFactoryPostProcessor,BeanFactoryPostProcessor 的執(zhí)行時(shí)機(jī)比較早,從下面這張流程圖中可以看到,BeanFactoryPostProcessor 在正常的 Bean 初始化之前就執(zhí)行了。

圖片圖片

那么對(duì)于想要提前初始化的 Bean,我們可以在 BeanFactoryPostProcessor 中手動(dòng)調(diào)用,類似下面這樣:

@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        //想要提前初始化的 Bean 在這里執(zhí)行
        beanFactory.getBean("serviceB");
    }
}

三、小結(jié)

多個(gè)相同類型的 Bean 該如何確保其執(zhí)行順序?這個(gè)靠 @Order 注解或者 Ordered 接口來(lái)解決。但是這兩者并不能解決 Bean 的加載順序。Bean 的加載順序有兩種方式可以調(diào)整:

  1. 通過(guò) @DependsOn 注解加載。
  2. 手動(dòng)在 BeanFactoryPostProcessor#postProcessBeanFactory 方法中提前調(diào)用 getBean 方法去初始化 Bean。

如果小伙伴們想要徹底掌握 Spring 源碼,那么不妨看看松哥錄制的 Spring 源碼視頻教程。

這套視頻教程基于目前最新的 Spring6 錄制,一共有 204 集約 40 個(gè)小時(shí),從 Spring 基本用法講起,一直講到源碼分析。

以下是完整視頻目錄:

├── 01.基礎(chǔ)用法
│   ├── 01.IoC基礎(chǔ)
│   │   ├── 01.Spring框架介紹-核心容器.mp4
│   │   ├── 02.Spring框架介紹-數(shù)據(jù)訪問(wèn)和通信.mp4
│   │   ├── 03.Spring框架介紹-Web模塊.mp4
│   │   ├── 04.Spring框架介紹-AOP和測(cè)試.mp4
│   │   ├── 05.什么是IoC.mp4
│   │   ├── 06.自定義一個(gè)簡(jiǎn)單的IoC.mp4
│   │   ├── 07.向Spring容器注冊(cè)Bean.mp4
│   │   ├── 08.從Spring容器獲取Bean.mp4
│   │   ├── 09.id屬性和name屬性.mp4
│   │   ├── 10.基本屬性注入.mp4
│   │   ├── 11.復(fù)雜屬性注入.mp4
│   │   ├── 12.構(gòu)造器注入.mp4
│   │   ├── 13.p名稱空間注入.mp4
│   │   ├── 14.屬性自動(dòng)注入.mp4
│   │   ├── 15.配置文件加載.mp4
│   │   ├── 16.Java代碼配置IoC.mp4
│   │   ├── 17.BeanName自動(dòng)生成原理.mp4
│   │   ├── 18.id和name屬性處理原理.mp4
│   │   ├── 19.Bean 的作用域.mp4
│   │   ├── 20.singleton 和 prototype 的區(qū)別.mp4
│   │   ├── 21.條件注解詳解.mp4
│   │   ├── 22.多環(huán)境切換.mp4
│   │   ├── 23.Profile原理分析.mp4
│   │   ├── 24.自定義Profile.mp4
│   │   ├── 25.Bean的依賴關(guān)系.mp4
│   │   ├── 26.FactoryBean用法.mp4
│   │   ├── 27.抽取Bean的公共屬性.mp4
│   │   ├── 28.父子容器問(wèn)題.mp4
│   │   ├── 29.@Configuration注解的作用.mp4
│   │   ├── 30.Bean自動(dòng)掃描.mp4
│   │   └── 31.屬性值注入.mp4
│   ├── 02.AOP基礎(chǔ)
│   │   ├── 01.靜態(tài)代理.mp4
│   │   ├── 02.編譯時(shí)增強(qiáng)和運(yùn)行時(shí)增強(qiáng).mp4
│   │   ├── 03.編譯時(shí)增強(qiáng).mp4
│   │   ├── 04.運(yùn)行時(shí)增強(qiáng)-JDK.mp4
│   │   ├── 05.運(yùn)行時(shí)增強(qiáng)-CGLIB.mp4
│   │   ├── 06.什么是Spring AOP.mp4
│   │   ├── 07.SpringAOP和AspectJAOP.mp4
│   │   ├── 08.Spring AOP核心概念.mp4
│   │   ├── 09.Spring AOP入門用法.mp4
│   │   ├── 10.五種通知.mp4
│   │   ├── 11.Java代碼配置AOP.mp4
│   │   ├── 12.SpringAOP底層代理.mp4
│   │   └── 13.通過(guò)注解定義AOP攔截規(guī)則.mp4
│   ├── 03.JdbcTemplate
│   │   ├── 01.JdbcTemplate基本操作.mp4
│   │   ├── 02.增刪改查.mp4
│   │   └── 03.通過(guò)變量名傳遞參數(shù).mp4
│   └── 04.事務(wù)
│       ├── 01.事務(wù)簡(jiǎn)介.mp4
│       ├── 02.編程式事務(wù).mp4
│       ├── 03.XML配置聲明式事務(wù).mp4
│       ├── 04.Java配置聲明式事務(wù).mp4
│       ├── 05.Java+XML配置聲明式事務(wù).mp4
│       ├── 06.自定義事務(wù)注解.mp4
│       ├── 07.事務(wù)屬性-隔離級(jí)別.mp4
│       ├── 08.事務(wù)屬性-傳播性.mp4
│       ├── 09.事務(wù)屬性-傳播性2.mp4
│       ├── 10.事務(wù)屬性-回滾規(guī)則.mp4
│       ├── 11.事務(wù)屬性-只讀事務(wù).mp4
│       ├── 12.事務(wù)屬性-超時(shí)時(shí)間.mp4
│       └── 13.事務(wù)失效的場(chǎng)景.mp4
└── 02.進(jìn)階用法
    ├── 001.通過(guò)name屬性定義別名.mp4
    ├── 002.通過(guò)alias標(biāo)簽定義別名.mp4
    ├── 003.別名處理接口AliasRegistry.mp4
    ├── 004.aliasMap變量.mp4
    ├── 005.allowAliasOverriding.mp4
    ├── 006.hasAlias.mp4
    ├── 007.removeAlias和isAlias.mp4
    ├── 008.getAliases.mp4
    ├── 009.checkForAliasCircle.mp4
    ├── 010.canonicalName.mp4
    ├── 011.registerAlias.mp4
    ├── 012.resolveAliases.mp4
    ├── 013.name屬性解析原理.mp4
    ├── 014.alias標(biāo)簽解析.mp4
    ├── 015.DefaultListableBeanFactory.mp4
    ├── 016.StaticListableBeanFactory.mp4
    ├── 017.SimpleJndiBeanFactory.mp4
    ├── 018.ApplicationContext.mp4
    ├── 019.FactoryBean&SmartFactoryBean.mp4
    ├── 020.FactoryBean處理思路.mp4
    ├── 021.Bean提前加載流程分析.mp4
    ├── 022.isFactoryBean方法分析.mp4
    ├── 023.getBean中&的處理邏輯.mp4
    ├── 024.BeanDefinition簡(jiǎn)介.mp4
    ├── 025.RootBeanDefinition.mp4
    ├── 026.ChildBeanDefinition.mp4
    ├── 027.GenericBeanDefinition.mp4
    ├── 028.AnnotatedGenericBeanDefinition.mp4
    ├── 029.ScannedGenericBeanDefinition.mp4
    ├── 030.ConfigurationClassBeanDefinition.mp4
    ├── 031.CreateFromClassBeanDefinition.mp4
    ├── 032.ClassDerivedBeanDefinition.mp4
    ├── 033.加載XML配置的兩種方式.mp4
    ├── 034.BeanDefinitionReader.mp4
    ├── 035.PropertiesBeanDefinitionReader.mp4
    ├── 036.XmlBeanDefinitionReader.mp4
    ├── 037.配置類解析為BeanDefinition.mp4
    ├── 038.@Scope注解高級(jí)用法.mp4
    ├── 039.編程式AOP.mp4
    ├── 040.編程式AOP之target方法分析.mp4
    ├── 041.TargetSource體系結(jié)構(gòu).mp4
    ├── 042.SimpleBeanTargetSource.mp4
    ├── 043.自定義TargetSource.mp4
    ├── 044.引介增強(qiáng).mp4
    ├── 045.啟動(dòng)類上的@Scope注解代理原理.mp4
    ├── 046.常規(guī)類上的@Scope注解.mp4
    ├── 047.Java配置中的@Scope代理.mp4
    ├── 048.導(dǎo)入配置類上的@Scope注解.mp4
    ├── 049.@Configuration注解存在的意義是什么.mp4
    ├── 050.@Configuration-Vs-@Component.mp4
    ├── 051.@Configuration原理分析.mp4
    ├── 052.@Configuration的兩種模式Full和Lite.mp4
    ├── 053.詳細(xì)演示Full和Lite模式.mp4
    ├── 054.Full模式和Lite模式特點(diǎn)總結(jié).mp4
    ├── 055.@Configuration注解解析源碼分析.mp4
    ├── 056.@Configuration注解解析源碼分析-2.mp4
    ├── 057.條件注解高級(jí)用法.mp4
    ├── 058.條件注解高級(jí)用法補(bǔ)充.mp4
    ├── 059.條件注解原理分析.mp4
    ├── 060.beanName自動(dòng)生成場(chǎng)景.mp4
    ├── 061.beanName生成器分析.mp4
    ├── 062.AnnotationBeanNameGenerator.mp4
    ├── 063.BeanFactoryPostProcessor和BeanPostProcessor.mp4
    ├── 064.BeanFactoryPostProcessor案例.mp4
    ├── 065.BeanFactoryPostProcessor典型應(yīng)用場(chǎng)景.mp4
    ├── 066.Properties加載原理分析.mp4
    ├── 067.BeanDefinitionRegistryPostProcessor.mp4
    ├── 068.BeanFactoryPostProcessor作用時(shí)機(jī)分析.mp4
    ├── 069.BeanPostProcessor接口分析.mp4
    ├── 070.BeanPostProcessor實(shí)踐.mp4
    ├── 071.BeanPostProcessor實(shí)現(xiàn)AOP.mp4
    ├── 072.MergedBeanDefinitionPostProcessor.mp4
    ├── 073.BeanPostProcessor原理分析.mp4
    ├── 074.合并BeanDefinition原理分析.mp4
    ├── 075.合并BeanDefinition源碼分析.mp4
    ├── 076.父子容器原理分析.mp4
    ├── 077.事件基本用法.mp4
    ├── 078.事件是阻塞還是非阻塞.mp4
    ├── 079.手動(dòng)注冊(cè)事件監(jiān)聽器.mp4
    ├── 080.事件三大組件.mp4
    ├── 081.Java類定義的事件監(jiān)聽器.mp4
    ├── 082.Java類定義的事件監(jiān)聽器-補(bǔ)充.mp4
    ├── 083.通過(guò)Java注解定義的事件監(jiān)聽器.mp4
    ├── 084.ApplicationEventPublisher.mp4
    ├── 085.ApplicationEventMulticaster.mp4
    ├── 086.Spring事件補(bǔ)充.mp4
    ├── 087.Java國(guó)際化.mp4
    ├── 088.Spring國(guó)際化.mp4
    ├── 089.MessageSource層級(jí)關(guān)系.mp4
    ├── 090.getMessage方法原理分析.mp4
    ├── 091.解析無(wú)參的key.mp4
    ├── 092.解析有參key.mp4
    ├── 093.Lifecycle基本用法.mp4
    ├── 094.SmartLifecycle基本用法.mp4
    ├── 095.Lifecycle中start方法執(zhí)行原理.mp4
    ├── 096.Lifecycle中stop方法執(zhí)行原理.mp4
    ├── 097.編程式AOP.mp4
    ├── 098.動(dòng)態(tài)代理對(duì)象創(chuàng)建流程.mp4
    ├── 099.JDK和CGLIB動(dòng)態(tài)代理分析.mp4
    ├── 100.Advisor詳解.mp4
    ├── 101.自定義切面對(duì)象Advisor.mp4
    ├── 102.重載方法攔截規(guī)則.mp4
    ├── 103.攔截所有方法.mp4
    ├── 104.默認(rèn)配置的Pointcut對(duì)象.mp4
    ├── 105.Pointcut經(jīng)典寫法.mp4
    ├── 106.Pointcut分類.mp4
    ├── 107.StaticMethodMatcherPointcut.mp4
    ├── 108.StaticMethodMatcherPointcut-2.mp4
    ├── 109.DynamicMethodMatcherPointcut.mp4
    ├── 110.AnnotationMatchingPointcut.mp4
    ├── 111.ControlFlowPointcut.mp4
    ├── 112.ComposablePointcut.mp4
    ├── 113.提前返回Bean的機(jī)會(huì).mp4
    ├── 114.提前AOP的機(jī)會(huì).mp4
    ├── 115.理解兩個(gè)關(guān)鍵變量.mp4
    ├── 116.特殊的beanName.mp4
    ├── 117.自定義TargetSourceCreator.mp4
    ├── 118.提前AOP實(shí)踐.mp4
    ├── 119.AOP創(chuàng)建的契機(jī).mp4
    ├── 120.AOP對(duì)象生成整體思路.mp4
    ├── 121.AOP對(duì)象創(chuàng)建詳細(xì)流程分析.mp4
    ├── 122.Bean的獲取思路.mp4
    ├── 123.getBean方法整體思路分析.mp4
    ├── 124.從三級(jí)緩存中加載Bean.mp4
    ├── 125.從parent中加載Bean.mp4
    ├── 126.檢查@DependOn注解.mp4
    ├── 127.不同Scope獲取Bean實(shí)例.mp4
    ├── 128.生成的Bean類型檢查.mp4
    ├── 129.createBean方法分析.mp4
    ├── 130.doCreateBean-1.mp4
    ├── 131.循環(huán)依賴-二級(jí)緩存.mp4
    ├── 132.循環(huán)依賴-三級(jí)緩存.mp4
    ├── 133.循環(huán)依賴-三級(jí)緩存-補(bǔ)充.mp4
    ├── 134.循環(huán)依賴源碼分析-1.mp4
    ├── 135.循環(huán)依賴源碼分析-2.mp4
    ├── 136.循環(huán)依賴源碼分析-3.mp4
    ├── 137.Bean的生命周期-1.mp4
    ├── 138.Bean的生命周期-2.mp4
    ├── 139.Bean的生命周期-3.mp4
    ├── 140.Bean的實(shí)例化-1.mp4
    ├── 141.Bean的實(shí)例化-2.mp4
    ├── 142.Bean的屬性注入.mp4
    ├── 143.getBean方法.mp4
    └── 144.小結(jié).mp4

責(zé)任編輯:武曉燕 來(lái)源: 江南一點(diǎn)雨
相關(guān)推薦

2020-07-15 10:00:45

springbootbeanJava

2023-09-28 08:15:05

SpringBean加載

2024-01-23 08:47:13

BeanSpring加載方式

2009-06-17 17:04:37

BeanFactorySpring

2024-02-23 10:33:34

SpringBean容器

2022-06-23 10:47:57

Spring容器工具

2011-03-18 09:27:00

Spring

2022-09-02 08:19:37

spring配置加載

2021-03-08 08:40:25

Spring Bean 創(chuàng)建單例對(duì)象

2009-06-17 17:20:14

BeanFactorySpring

2023-10-25 10:21:24

瀏覽器HTTP請(qǐng)求

2024-05-28 07:55:31

SpringBean用域

2024-03-14 10:47:12

Spring生命周期阿里

2021-05-11 07:42:59

BeanSpring屬性

2023-11-03 08:19:18

SpringBean容器

2020-10-15 12:52:46

SpringbootJava編程語(yǔ)言

2022-09-16 11:41:17

Spring代碼

2011-04-02 15:25:41

Spring

2020-12-11 08:04:22

SpringAOPBean

2012-02-14 13:39:57

Java
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)