淺析SpringBoot2底層注解@Conditional@ImportResource
SpringBoot2底層注解
一、@ImportResource
@Conditional注解,是根據(jù)條件進(jìn)行裝配。滿足了 Conditional 指定的條件,就進(jìn)行組件的注入。
另外@Conditional是個(gè)根注解,在idea里使用 ctrl+H 可以打開它的結(jié)構(gòu)。
可以看到有許多的派生注解,每個(gè)注解都代表著一種功能。比如:
@ConditionalOnBean:當(dāng)容器中存在指定的組件,才會做某些事情。
@ConditionalOnMissingBean:當(dāng)容器中沒有指定的組件,才會做某些事情。
@ConditionalOnClass:當(dāng)容器中存在指定的類。
@ConditionalOnMissingClass:當(dāng)容器中不存在指定的類。
@ConditionalOnResource:項(xiàng)目類路徑里存在某個(gè)資源的時(shí)候。
@ConditionalOnJava:當(dāng)是指定的 java 版本號。
@ConditionalOnWebApplication:當(dāng)應(yīng)用是一個(gè) web 應(yīng)用的時(shí)候。
@ConditionalOnNotWebApplication:當(dāng)應(yīng)用不是一個(gè) web 應(yīng)用的時(shí)候。
@ConditionalOnProperty:當(dāng)配置文件里存在指定屬性的時(shí)候。
示例
以@ConditionalOnBean為例,演示一下用法。
還是看一下之前 MyConfig 類中的方法:
@Import({User.class, DBHelper.class}) @Configuration(proxyBeanMethods = true) public class MyConfig { @Bean("user1") public User user01(){ User pingguo = new User("pingguo",20); pingguo.setPet(tomcatPet()); return pingguo; } // @Bean("pet1") public Pet tomcatPet(){ return new Pet("tomcat"); } }
在這里,我把pet1這個(gè)組件給注釋掉,現(xiàn)在tomcatPet()其實(shí)就是個(gè)普通的類方法。
先嘗試在主運(yùn)行類的 main 方法里獲取一下 這 2 個(gè) 組件:
@SpringBootApplication(scanBasePackages = "com.pingguo") public class MainApplication { public static void main(String[] args) { // 返回IOC容器 final ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args); boolean tomcatPet = run.containsBean("pet1"); System.out.println("容器中存在 pet1 的組件:" + tomcatPet); boolean user1 = run.containsBean("user1"); System.out.println("容器中存在 user1 的組件:" + user1); } }
運(yùn)行一下,查看結(jié)果:
果然,是不存在pet1組件的,因?yàn)锧bean這個(gè)注解被我注釋掉了。
OK,現(xiàn)在我有個(gè)需求,因?yàn)閡ser1組件依賴pet1組件,如果沒有pet1,我希望user1組件也直接別注冊了。
這時(shí)候就可以使用@ConditionalOnBean注解來完成。
@Import({User.class, DBHelper.class}) @Configuration(proxyBeanMethods = true) public class MyConfig { @ConditionalOnBean(name = "pet1") @Bean("user1") public User user01(){ User pingguo = new User("pingguo",20); pingguo.setPet(tomcatPet()); return pingguo; } // @Bean("pet1") public Pet tomcatPet(){ return new Pet("tomcat"); } }
在 user1組件上加上@ConditionalOnBean(name = "pet1"),當(dāng)沒有pet1組件,就不注冊user1組件。
現(xiàn)在再運(yùn)行 main 方法測試一下,應(yīng)該都是 false,2個(gè)組件都不存在。
作用在類上
@ConditionalOnBean(name = "pet1")如果我放在類上:
@ConditionalOnBean(name = "pet1") // 放在類上 @Import({User.class, DBHelper.class}) @Configuration(proxyBeanMethods = true) public class MyConfig { @Bean("user1") public User user01(){ User pingguo = new User("pingguo",20); pingguo.setPet(tomcatPet()); return pingguo; } @Bean("pet22") public Pet tomcatPet(){ return new Pet("tomcat"); } }
現(xiàn)在就表示,當(dāng)存在pet1組件的時(shí)候,這個(gè)類下面的所有才會生效。
這里我改了下面的組件注冊變成pet22,也就是說當(dāng)存在pet1組件的時(shí)候,就會注冊user1和pet22。
在 main 方法里增加打印pet22,查看是否存在:
... ... boolean pet22 = run.containsBean("pet22"); System.out.println("容器中存在 pet22 的組件:" + pet22); ... ...
運(yùn)行一下:
因?yàn)椴淮嬖趐et1這個(gè)組件,所有MyConfig類下面的2個(gè)組件user1和pet22的注冊都不生效。
二、@ImportResource
@ImportResource注解是用來導(dǎo)入資源。
比如,之前我們可能會在 spring 配置文件中寫非常多的組件導(dǎo)入:
... ... <bean id="haha" class="com.pingguo.boot.bean.User"> <property name="name" value="pingguo"></property> <property name="age" value="20"></property> </bean> <bean id="hehe" class="com.pingguo.boot.bean.User"> <property name="name" value="tomcat"></property> </bean>
這里只是demo,實(shí)際工程中可能會存在很多 bean,如果想要逐個(gè)遷移成注解的方式,會很麻煩。
但是現(xiàn)在容器里又是沒有這些組件的,在 main 方法里輸出測試一下:
boolean haha = run.containsBean("haha"); System.out.println("容器中存在 haha 的組件:" + haha); boolean hehe = run.containsBean("hehe"); System.out.println("容器中存在 hehe 的組件:" + hehe);
因?yàn)檫@些組件聲明在 xml 里,springboot 也并不知道這些是干嘛的。
這時(shí)候就可以使用@ImportResource來導(dǎo)入這些組件:
//@ConditionalOnBean(name = "pet1") @Import({User.class, DBHelper.class}) @Configuration(proxyBeanMethods = true) @ImportResource("classpath:beans.xml") //配置文件的類路徑 public class MyConfig { @Bean("user1") public User user01(){ User pingguo = new User("pingguo",20); pingguo.setPet(tomcatPet()); return pingguo; } @Bean("pet22") public Pet tomcatPet(){ return new Pet("tomcat"); } }
這個(gè)時(shí)候再運(yùn)行測試一下:
xml 配置文件里的組件被成功解析注冊到了容器中。
以上就是淺析SpringBoot2底層注解@Conditional@ImportResource的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot2底層注解的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
SpringBoot工程打包與運(yùn)行的實(shí)現(xiàn)詳解
本文主要介紹了SpringBoot工程的打包與運(yùn)行的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-07-07深入了解Java語言中的并發(fā)性選項(xiàng)有何不同
這篇文章主要介紹了深入了解Java語言中的并發(fā)性選項(xiàng)有何不同,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,,需要的朋友可以參考下2019-06-06SpringBoot自動配置Quartz的實(shí)現(xiàn)步驟
本文主要介紹了SpringBoot自動配置Quartz的實(shí)現(xiàn)步驟,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-11-11springboot使用shiro-整合redis作為緩存的操作
這篇文章主要介紹了springboot使用shiro-整合redis作為緩存的操作,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-06-06Java8 Stream對兩個(gè) List 遍歷匹配數(shù)據(jù)的優(yōu)化處理操作
這篇文章主要介紹了Java8 Stream對兩個(gè) List 遍歷匹配數(shù)據(jù)的優(yōu)化處理操作,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-08-08