自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

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

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

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

一、@Order 注解和 Ordered 接口

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

1.1 用途

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

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

1.2 使用場景

經典使用場景。

攔截器排序

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

Spring Security Filters(過濾器)

在 Spring Security 中,過濾器鏈的順序通過 @Order 來定義,確保正確的安全處理流程。這個在松哥最近的教程中和大家詳細介紹過了。

圖片圖片

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

當有多個監(jiān)聽同一事件的監(jiān)聽器時,可以通過 @Order 來控制它們的觸發(fā)順序。

Bean 的集合注入

當一個 Bean 依賴于一個特定類型的 Bean 集合時,帶有 @Order 注解的 Bean 將按照指定順序被注入。

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

但是?。。?/p>

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

二、如何設置 Bean 的加載順序?

有兩種方式來設置 Bean 的加載順序。

2.1 @DependsOn

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

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

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

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

相關的源碼在 AbstractBeanFactory#doGetBean 方法中:

圖片圖片

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

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

2.2 BeanFactoryPostProcessor

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

圖片圖片

那么對于想要提前初始化的 Bean,我們可以在 BeanFactoryPostProcessor 中手動調用,類似下面這樣:

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

三、小結

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

  1. 通過 @DependsOn 注解加載。
  2. 手動在 BeanFactoryPostProcessor#postProcessBeanFactory 方法中提前調用 getBean 方法去初始化 Bean。

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

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

以下是完整視頻目錄:

├── 01.基礎用法
│   ├── 01.IoC基礎
│   │   ├── 01.Spring框架介紹-核心容器.mp4
│   │   ├── 02.Spring框架介紹-數(shù)據訪問和通信.mp4
│   │   ├── 03.Spring框架介紹-Web模塊.mp4
│   │   ├── 04.Spring框架介紹-AOP和測試.mp4
│   │   ├── 05.什么是IoC.mp4
│   │   ├── 06.自定義一個簡單的IoC.mp4
│   │   ├── 07.向Spring容器注冊Bean.mp4
│   │   ├── 08.從Spring容器獲取Bean.mp4
│   │   ├── 09.id屬性和name屬性.mp4
│   │   ├── 10.基本屬性注入.mp4
│   │   ├── 11.復雜屬性注入.mp4
│   │   ├── 12.構造器注入.mp4
│   │   ├── 13.p名稱空間注入.mp4
│   │   ├── 14.屬性自動注入.mp4
│   │   ├── 15.配置文件加載.mp4
│   │   ├── 16.Java代碼配置IoC.mp4
│   │   ├── 17.BeanName自動生成原理.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的依賴關系.mp4
│   │   ├── 26.FactoryBean用法.mp4
│   │   ├── 27.抽取Bean的公共屬性.mp4
│   │   ├── 28.父子容器問題.mp4
│   │   ├── 29.@Configuration注解的作用.mp4
│   │   ├── 30.Bean自動掃描.mp4
│   │   └── 31.屬性值注入.mp4
│   ├── 02.AOP基礎
│   │   ├── 01.靜態(tài)代理.mp4
│   │   ├── 02.編譯時增強和運行時增強.mp4
│   │   ├── 03.編譯時增強.mp4
│   │   ├── 04.運行時增強-JDK.mp4
│   │   ├── 05.運行時增強-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.通過注解定義AOP攔截規(guī)則.mp4
│   ├── 03.JdbcTemplate
│   │   ├── 01.JdbcTemplate基本操作.mp4
│   │   ├── 02.增刪改查.mp4
│   │   └── 03.通過變量名傳遞參數(shù).mp4
│   └── 04.事務
│       ├── 01.事務簡介.mp4
│       ├── 02.編程式事務.mp4
│       ├── 03.XML配置聲明式事務.mp4
│       ├── 04.Java配置聲明式事務.mp4
│       ├── 05.Java+XML配置聲明式事務.mp4
│       ├── 06.自定義事務注解.mp4
│       ├── 07.事務屬性-隔離級別.mp4
│       ├── 08.事務屬性-傳播性.mp4
│       ├── 09.事務屬性-傳播性2.mp4
│       ├── 10.事務屬性-回滾規(guī)則.mp4
│       ├── 11.事務屬性-只讀事務.mp4
│       ├── 12.事務屬性-超時時間.mp4
│       └── 13.事務失效的場景.mp4
└── 02.進階用法
    ├── 001.通過name屬性定義別名.mp4
    ├── 002.通過alias標簽定義別名.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標簽解析.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簡介.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注解高級用法.mp4
    ├── 039.編程式AOP.mp4
    ├── 040.編程式AOP之target方法分析.mp4
    ├── 041.TargetSource體系結構.mp4
    ├── 042.SimpleBeanTargetSource.mp4
    ├── 043.自定義TargetSource.mp4
    ├── 044.引介增強.mp4
    ├── 045.啟動類上的@Scope注解代理原理.mp4
    ├── 046.常規(guī)類上的@Scope注解.mp4
    ├── 047.Java配置中的@Scope代理.mp4
    ├── 048.導入配置類上的@Scope注解.mp4
    ├── 049.@Configuration注解存在的意義是什么.mp4
    ├── 050.@Configuration-Vs-@Component.mp4
    ├── 051.@Configuration原理分析.mp4
    ├── 052.@Configuration的兩種模式Full和Lite.mp4
    ├── 053.詳細演示Full和Lite模式.mp4
    ├── 054.Full模式和Lite模式特點總結.mp4
    ├── 055.@Configuration注解解析源碼分析.mp4
    ├── 056.@Configuration注解解析源碼分析-2.mp4
    ├── 057.條件注解高級用法.mp4
    ├── 058.條件注解高級用法補充.mp4
    ├── 059.條件注解原理分析.mp4
    ├── 060.beanName自動生成場景.mp4
    ├── 061.beanName生成器分析.mp4
    ├── 062.AnnotationBeanNameGenerator.mp4
    ├── 063.BeanFactoryPostProcessor和BeanPostProcessor.mp4
    ├── 064.BeanFactoryPostProcessor案例.mp4
    ├── 065.BeanFactoryPostProcessor典型應用場景.mp4
    ├── 066.Properties加載原理分析.mp4
    ├── 067.BeanDefinitionRegistryPostProcessor.mp4
    ├── 068.BeanFactoryPostProcessor作用時機分析.mp4
    ├── 069.BeanPostProcessor接口分析.mp4
    ├── 070.BeanPostProcessor實踐.mp4
    ├── 071.BeanPostProcessor實現(xiàn)AOP.mp4
    ├── 072.MergedBeanDefinitionPostProcessor.mp4
    ├── 073.BeanPostProcessor原理分析.mp4
    ├── 074.合并BeanDefinition原理分析.mp4
    ├── 075.合并BeanDefinition源碼分析.mp4
    ├── 076.父子容器原理分析.mp4
    ├── 077.事件基本用法.mp4
    ├── 078.事件是阻塞還是非阻塞.mp4
    ├── 079.手動注冊事件監(jiān)聽器.mp4
    ├── 080.事件三大組件.mp4
    ├── 081.Java類定義的事件監(jiān)聽器.mp4
    ├── 082.Java類定義的事件監(jiān)聽器-補充.mp4
    ├── 083.通過Java注解定義的事件監(jiān)聽器.mp4
    ├── 084.ApplicationEventPublisher.mp4
    ├── 085.ApplicationEventMulticaster.mp4
    ├── 086.Spring事件補充.mp4
    ├── 087.Java國際化.mp4
    ├── 088.Spring國際化.mp4
    ├── 089.MessageSource層級關系.mp4
    ├── 090.getMessage方法原理分析.mp4
    ├── 091.解析無參的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.動態(tài)代理對象創(chuàng)建流程.mp4
    ├── 099.JDK和CGLIB動態(tài)代理分析.mp4
    ├── 100.Advisor詳解.mp4
    ├── 101.自定義切面對象Advisor.mp4
    ├── 102.重載方法攔截規(guī)則.mp4
    ├── 103.攔截所有方法.mp4
    ├── 104.默認配置的Pointcut對象.mp4
    ├── 105.Pointcut經典寫法.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的機會.mp4
    ├── 114.提前AOP的機會.mp4
    ├── 115.理解兩個關鍵變量.mp4
    ├── 116.特殊的beanName.mp4
    ├── 117.自定義TargetSourceCreator.mp4
    ├── 118.提前AOP實踐.mp4
    ├── 119.AOP創(chuàng)建的契機.mp4
    ├── 120.AOP對象生成整體思路.mp4
    ├── 121.AOP對象創(chuàng)建詳細流程分析.mp4
    ├── 122.Bean的獲取思路.mp4
    ├── 123.getBean方法整體思路分析.mp4
    ├── 124.從三級緩存中加載Bean.mp4
    ├── 125.從parent中加載Bean.mp4
    ├── 126.檢查@DependOn注解.mp4
    ├── 127.不同Scope獲取Bean實例.mp4
    ├── 128.生成的Bean類型檢查.mp4
    ├── 129.createBean方法分析.mp4
    ├── 130.doCreateBean-1.mp4
    ├── 131.循環(huán)依賴-二級緩存.mp4
    ├── 132.循環(huán)依賴-三級緩存.mp4
    ├── 133.循環(huán)依賴-三級緩存-補充.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的實例化-1.mp4
    ├── 141.Bean的實例化-2.mp4
    ├── 142.Bean的屬性注入.mp4
    ├── 143.getBean方法.mp4
    └── 144.小結.mp4

責任編輯:武曉燕 來源: 江南一點雨
相關推薦

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配置加載

2009-06-17 17:20:14

BeanFactorySpring

2021-03-08 08:40:25

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

2023-10-25 10:21:24

瀏覽器HTTP請求

2024-05-28 07:55:31

SpringBean用域

2021-05-11 07:42:59

BeanSpring屬性

2024-03-14 10:47:12

Spring生命周期阿里

2023-11-03 08:19:18

SpringBean容器

2020-10-15 12:52:46

SpringbootJava編程語言

2022-09-16 11:41:17

Spring代碼

2011-04-02 15:25:41

Spring

2012-02-14 13:39:57

Java

2020-12-11 08:04:22

SpringAOPBean
點贊
收藏

51CTO技術棧公眾號