深入理解Spring bean加載順序
最近在開(kāi)發(fā)過(guò)程中遇到一個(gè)Spring bean加載順序的問(wèn)題,容器在啟動(dòng)的時(shí)候 會(huì)通過(guò)InitializingBean 的afterPropertiesSet 加載兩級(jí)緩存,但是加載的過(guò)程中因?yàn)闆](méi)有將load的容器對(duì)象加載到Spring 容器中導(dǎo)致NPE ,所以今天來(lái)鞏固一下spring bean的加載順序會(huì)受那些影響
在默認(rèn)配置下,Spring的Bean加載順序并不是隨機(jī)的,但也不是嚴(yán)格按某種預(yù)定順序進(jìn)行的。默認(rèn)情況下,Spring會(huì)按以下策略來(lái)加載和初始化Bean:
1. 加載順序的確定性
- 配置順序:在Spring XML配置文件或Java配置類中定義的Bean,通常按照定義的順序加載。
- 注解掃描順序:在使用組件掃描(例如
@ComponentScan
)時(shí),Spring會(huì)按照類路徑掃描的順序加載Bean。但這個(gè)順序在不同的運(yùn)行環(huán)境下可能有所不同,因?yàn)轭惵窂綊呙璧捻樞蛉Q于文件系統(tǒng)或JAR包的排列方式。
2. 依賴關(guān)系的解析
Spring會(huì)在加載和初始化Bean時(shí)解析Bean之間的依賴關(guān)系,確保依賴的Bean先加載和初始化。這意味著如果Bean A依賴于Bean B,那么Bean B會(huì)先于Bean A加載和初始化。
3. Bean初始化順序
@DependsOn
注解:可以使用@DependsOn
注解明確指定一個(gè)Bean依賴于另外一個(gè)或多個(gè)Bean。這樣,被依賴的Bean會(huì)先初始化。depends-on
屬性:在XML配置中,可以使用depends-on
屬性明確指定一個(gè)Bean依賴于另外一個(gè)或多個(gè)Bean。
4. FactoryBean
FactoryBean
會(huì)優(yōu)先于普通Bean進(jìn)行初始化,因?yàn)樗鼈冐?fù)責(zé)創(chuàng)建其他Bean的實(shí)例。
5. 生命周期回調(diào)方法
Spring會(huì)確保Bean按照以下順序進(jìn)行生命周期回調(diào):
BeanPostProcessor
的postProcessBeforeInitialization
方法- 初始化回調(diào)(例如
InitializingBean
的afterPropertiesSet
方法或自定義init-method
) BeanPostProcessor
的postProcessAfterInitialization
方法
示例代碼和說(shuō)明
以下是一些示例代碼,展示了不同情況下的Bean加載順序:
XML配置
<bean id="beanA" class="com.example.BeanA"/> <bean id="beanB" class="com.example.BeanB" depends-on="beanA"/>
在這種情況下,beanA
會(huì)先于beanB
加載和初始化。
注解配置
@Configuration @ComponentScan(basePackages = "com.example") public class AppConfig { @Bean @DependsOn("beanA") public BeanB beanB() { return new BeanB(); } @Bean public BeanA beanA() { return new BeanA(); } }
在這種配置中,beanA
會(huì)先于beanB
加載和初始化,因?yàn)?code>beanB使用了@DependsOn
注解。
檢查Bean加載順序的代碼示例
為了演示Spring Bean加載的順序,我們可以編寫(xiě)一個(gè)簡(jiǎn)單的Spring應(yīng)用,并在Bean的構(gòu)造方法中打印日志:
@Component public class BeanA { public BeanA() { System.out.println("BeanA instantiated"); } } @Component public class BeanB { public BeanB() { System.out.println("BeanB instantiated"); } } @Configuration @ComponentScan(basePackages = "com.example") public class AppConfig { public static void main(String[] args) { ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class); // Force initialization of beans context.getBean(BeanA.class); context.getBean(BeanB.class); } }
在這個(gè)示例中,如果運(yùn)行程序,控制臺(tái)輸出的順序?qū)?huì)表明Bean的加載順序。這種方式可以幫助我們驗(yàn)證在不同配置和環(huán)境下Bean的加載順序。
總結(jié)
在默認(rèn)配置下,Spring的Bean加載順序主要取決于Bean的定義順序、依賴關(guān)系和生命周期回調(diào)方法。雖然類路徑掃描的順序可能因運(yùn)行環(huán)境而異,但通過(guò)使用@DependsOn
注解和depends-on
屬性,可以顯式控制Bean的加載和初始化順序。Spring并不會(huì)隨機(jī)改變Bean的加載順序,而是遵循上述策略確保Bean在合理的順序中加載和初始化。
到此這篇關(guān)于深入理解Spring bean加載順序的文章就介紹到這了,更多相關(guān)Spring bean加載順序內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
詳解Java從后臺(tái)重定向(redirect)到另一個(gè)項(xiàng)目的方法
這篇文章主要介紹了詳解Java從后臺(tái)重定向(redirect)到另一個(gè)項(xiàng)目的方法,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2017-04-04SpringBoot @JsonDeserialize自定義Json序列化方式
這篇文章主要介紹了SpringBoot @JsonDeserialize自定義Json序列化方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-10-10ibatis學(xué)習(xí)之搭建Java項(xiàng)目
本文的主要內(nèi)容是簡(jiǎn)單介紹了ibatis和如何通過(guò)iBatis搭建JAVA項(xiàng)目,包含了一個(gè)相關(guān)實(shí)例,需要的朋友可以參考下。2017-09-09springboot如何靜態(tài)加載@configurationProperties
這篇文章主要介紹了springboot如何靜態(tài)加載@configurationProperties,本文一個(gè)錯(cuò)誤案例和成功案例結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2022-07-07QTabWidget標(biāo)簽實(shí)現(xiàn)雙擊關(guān)閉的方法(推薦)
這篇文章主要介紹了QTabWidget標(biāo)簽實(shí)現(xiàn)雙擊關(guān)閉的方法(推薦)的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-06-06SpringBoot使用hutool-captcha實(shí)現(xiàn)驗(yàn)證碼生成與驗(yàn)證
在springboot的登陸頁(yè)面中為了防止機(jī)器大規(guī)模注冊(cè),機(jī)器暴力破解數(shù)據(jù)密碼等危害,需要驗(yàn)證隨機(jī)生成的驗(yàn)證碼,本文主要介紹了SpringBoot使用hutool-captcha實(shí)現(xiàn)驗(yàn)證碼生成與驗(yàn)證,感興趣的可以了解一下2023-12-12SpringBoot實(shí)現(xiàn)本地文件存儲(chǔ)及預(yù)覽過(guò)程
這篇文章主要介紹了SpringBoot實(shí)現(xiàn)本地文件存儲(chǔ)及預(yù)覽過(guò)程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-11-11maven依賴關(guān)系中的<scope>provided</scope>使用詳解
這篇文章主要介紹了maven依賴關(guān)系中的<scope>provided</scope>使用詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-07-07