Spring之@DependsOn注解詳細解析
1、學習指引
Spring創(chuàng)建Bean時如何指定Bean的依賴順序呢?
在實際開發(fā)項目的過程中,經常會遇到這樣一種場景:在開發(fā)一個A功能模塊時,這個A功能模塊可能會依賴另一個B功能模塊。
此時,就需要先開發(fā)B功能模塊,然后在開發(fā)A功能模塊,在A功能模塊中調用B功能模塊的功能。
在Spring中創(chuàng)建Bean對象也是如此,可以通過某種方式指定Spring中創(chuàng)建Bean的依賴順序,Spring會根據創(chuàng)建Bean的依賴順序來創(chuàng)建對應的Bean對象。
這個指定創(chuàng)建Bean依賴順序的注解就是@DependsOn注解。
2、注解說明
@DependsOn注解是Spring中提供的一個指定Spring創(chuàng)建Bean的依賴順序的注解。
例如,在Spring中需要創(chuàng)建A對象和B對象,可以使用@DependsOn注解指定創(chuàng)建A對象時依賴B對象,此時,在Spring中就會先創(chuàng)建B對象,然后再創(chuàng)建A對象。
2.1、注解源碼
@DependsOn注解可以標注到類或方法上,可以控制bean的創(chuàng)建、初始化和銷毀方法的執(zhí)行順序。源碼詳見:org.springframework.context.annotation.DependsOn。
/** * @author Juergen Hoeller * @since 3.0 */ @Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface DependsOn { String[] value() default {}; }
從@DependsOn注解的源碼可以看出,@DependsOn注解是從Spring 3.0版本開始提供的注解。其中,只提供了一個String數組類型的value屬性,含義如下所示。
value:表示指定的Bean的唯一標識,被指定的Bean會在Spring創(chuàng)建當前Bean之前被創(chuàng)建。
2.2、注解使用場景
@DependsOn注解主要用于指定當前Bean對象所依賴的其他Bean對象。Spring在創(chuàng)建當前Bean之前,會先創(chuàng)建由@DependsOn注解指定的依賴Bean,在Spring中使用@DependsOn注解的場景通常會有以下幾種場景:
- 在某些情況下,Bean不是通過屬性或構造函數參數顯式依賴于另一個Bean的,但是卻需要在創(chuàng)建一個Bean對象之前,需要先創(chuàng)建另一個Bean對象,此時就可以使用@DependsOn注解。
- 在單例Bean的情況下@DependsOn既可以指定初始化依賴順序,也可以指定Bean相應的銷毀執(zhí)行順序。
- @DependsOn注解可標注到任何直接或間接帶有@Component注解的Bean或標注到@Bean注解的方法上,可以控制Bean的創(chuàng)建、初始化和銷毀方法執(zhí)行順序。
- 觀察者模式可以分為事件,事件源和監(jiān)聽器三個組件,如果在Spring中需要實現觀察者模式時,就可以使用@DependsOn注解實現監(jiān)聽器的Bean對象在事件源的Bean對象之前被創(chuàng)建。
3、使用案例
Spring的@DependsOn注解可以標注到類或方法上,所以,本節(jié)會列舉@DependsOn注解標注到類和方法上兩個案例
3.1、標注到類上的案例
本節(jié),主要使用@DependsOn注解標注到類上來實現Spring創(chuàng)建Bean的依賴順序案例,具體實現步驟如下所示。
3.1.1、新建DependsOnClassA類
@Component(value = "dependsOnClassA") @DependsOn(value = {"dependsOnClassB"}) public class DependsOnClassA { private final Logger logger = LoggerFactory.getLogger(DependsOnClassA.class); public DependsOnClassA(){ logger.info("執(zhí)行DependsOnClassA的構造方法"); } }
可以看到,DependsOnClassA類上使用@Component注解標注,并且指定了Bean的名稱為dependsOnClassA,以及使用@DependsOn注解指定了依賴的Bean名稱為dependsOnClassB。
3.1.2、新建DependsOnClassB類
@Component(value = "dependsOnClassB") public class DependsOnClassB { private final Logger logger = LoggerFactory.getLogger(DependsOnClassB.class); public DependsOnClassB(){ logger.info("執(zhí)行DependsOnClassB的構造方法"); } }
可以看到,在DependsOnClassB類上標注了@Component注解,指定了Bean對象的名稱為dependsOnClassB。
由DependsOnClassA類和DependsOnClassB類可以看出,在Spring中創(chuàng)建DependsOnClassA類的對象時,會依賴DependsOnClassB類的對象。
所以,在Spring中,創(chuàng)建DependsOnClassA類的對象之前,會先創(chuàng)建DependsOnClassB類的對象
3.1.3、新建DependsOnConfig類
@Configuration @ComponentScan(basePackages = "io.binghe.spring.annotation.chapter07") public class DependsOnConfig { }
可以看到,DependsOnConfig類的實現比較簡單,在DependsOnConfig類上標注了@Configuration注解,表示這是一個Spring的配置類,并且使用@ComponentScan注解指定了掃描的基礎包名。
3.1.4、新建DependsOnTest類
public class DependsOnTest { public static void main(String[] args) { new AnnotationConfigApplicationContext(DependsOnConfig.class); } }
可以看到,DependsOnTest類作為測試案例的啟動類,整體實現比較簡單,就是在main()方法中創(chuàng)建Spring的IOC容器。
3.1.5、測試DependsOnTest類
運行DependsOnTest類中的main()方法,輸出的結果信息如下所示。
14:56:17.977 [main] INFO DependsOnClassB - 執(zhí)行DependsOnClassB的構造方法
14:56:17.978 [main] INFO DependsOnClassA - 執(zhí)行DependsOnClassA的構造方法
可以看到,當@DependsOn注解標注到類上時,Spring在創(chuàng)建標注了@DependsOn注解的類的Bean對象之前,會先創(chuàng)建使用@DependsOn注解指定的Bean對象。
3.2、標注到方法上的案例
3.2.1、新建DependsOnMethodA類
public class DependsOnMethodA { private final Logger logger = LoggerFactory.getLogger(DependsOnMethodA.class); public DependsOnMethodA(){ logger.info("執(zhí)行DependsOnMethodA的構造方法"); } }
可以看到,DependsOnMethodA類就是一個簡單的實體類,這里不再贅述。
3.2.2、新增DependsOnMethodB類
public class DependsOnMethodB { private final Logger logger = LoggerFactory.getLogger(DependsOnMethodB.class); public DependsOnMethodB(){ logger.info("執(zhí)行DependsOnMethodB的構造方法"); } }
可以看到,DependsOnMethodB類就是一個簡單的實體類,這里不再贅述。
3.2.3、修改DependsOnConfig類
在DependsOnConfig類中使用@Bean注解分別創(chuàng)建DependsOnMethodA類和DependsOnMethodB類的Bean對象,如下所示。
@DependsOn(value = {"dependsOnMethodB"}) @Bean(value = "dependsOnMethodA") public DependsOnMethodA dependsOnMethodA(){ return new DependsOnMethodA(); } @Bean(value = "dependsOnMethodB") public DependsOnMethodB dependsOnMethodB(){ return new DependsOnMethodB(); }
可以看到,在DependsOnConfig類中使用@Bean注解創(chuàng)建DependsOnMethodA類的Bean對象時,使用@DependsOn注解依賴了名稱為dependsOnMethodB的Bean對象。
3.2.4、測試DependsOnTest類
運行DependsOnTest類中的main()方法,輸出的結果信息如下所示。
15:16:24.523 [main] INFO DependsOnClassB - 執(zhí)行DependsOnClassB的構造方法
15:16:24.524 [main] INFO DependsOnClassA - 執(zhí)行DependsOnClassA的構造方法
15:16:24.528 [main] INFO DependsOnMethodB - 執(zhí)行DependsOnMethodB的構造方法
15:16:24.529 [main] INFO DependsOnMethodA - 執(zhí)行DependsOnMethodA的構造方法
可以看到,當@DependsOn注解標注到方法上時,Spring在執(zhí)行標注了@DependsOn注解的方法創(chuàng)建Bean對象前,先執(zhí)行其他方法來創(chuàng)建使用@DependsOn注解指定的Bean對象。
通過上述兩個案例得知:@DependsOn注解可以指定Spring中Bean對象創(chuàng)建的依賴順序,并且Spring在創(chuàng)建當前Bean之前,會先創(chuàng)建由@DependsOn注解指定的依賴Bean
到此這篇關于Spring之@DependsOn注解詳細解析的文章就介紹到這了,更多相關@DependsOn注解內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Java語言實現簡單FTP軟件 輔助功能模塊FTP站點管理實現(12)
這篇文章主要為大家詳細介紹了Java語言實現簡單FTP軟,輔助功能模塊FTP站點管理的實現方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-04-04關于spring中單例Bean引用原型Bean產生的問題及解決
這篇文章主要介紹了關于spring中單例Bean引用原型Bean產生的問題及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-06-06InputStreamReader 和FileReader的區(qū)別及InputStream和Reader的區(qū)別
這篇文章主要介紹了InputStreamReader 和FileReader的區(qū)別及InputStream和Reader的區(qū)別的相關資料,需要的朋友可以參考下2015-12-12