上一篇文章 你應該知道的 @ConfigurationProperties 註解的使用姿式,這一篇就夠了 介紹瞭如何經過 @ConfigurationProperties
註解靈活讀取配置屬性,這篇文章將介紹如何靈活配置 Spring Beanjava
當咱們構建一個 Spring 應用的時候,有時咱們想在知足指定條件的時候纔將某個 bean 加載到應用上下文中, 在Spring 4.0 時代,咱們能夠經過 @Conditional
註解來實現這類操做 git
咱們看到 @Conditional
註解接收的參數是 extends Condition 接口的泛型類,也就是說,咱們要使用 @Conditional
註解,只須要實現 Condition 接口並重寫其方法便可: github
看到接口的 matches 方法返回的是 boolean 類型,是否是和咱們自定義 validation annotation 有些相似,都是用來判斷是否知足指定條件。另外注意看,以上註解和接口都在 org.springframework.context.annotation
package 中web
終於到了 Spring Boot 時代,在這個全新的時代,Spring Boot 在 @Conditional
註解的基礎上進行了細化,無需出示複雜的介紹信 (實現 Condition 接口),只須要手持預約義好的 @ConditionalOnXxxx
註解印章的門票,若是驗證經過,就會走進 Application Context 大廳面試
Spring Boot 對 @Conditional
註解爲咱們作了細化,這些註解都定義在 org.springframework.boot.autoconfigure.condition
package 下 spring
逐個打開這 13 個註解,咱們發現這些註解上有相同的元註解: 多線程
從這些標記上咱們能夠了解以下內容:app
均可以應用在 TYPE 上,也就是說,Spring 自動掃描的一切類 (@Configuration, @Component, @Service, @Repository, or @Controller) 均可以經過添加相應的 @ConditionalOnXxxx
來判斷是否加載框架
均可以應用在 METHOD 上,因此有 @Bean 標記的方法也能夠應用這些註解spring-boot
都是用了 @Conditional
註解來標記,OnBeanCondition 等自定義 Condition 仍是實現了 Condition 接口的,換湯不換藥,沒什麼神祕的,只不過作了更具象的封裝罷了,來看類依賴圖:
其實看這些註解字面意思已經能理解這些註解的含義,可是咱們仍是要說明具體的使用以及一些注意事項,我按照我的使用頻次由高到低講解:
毫無疑問這個註解是榜首
這個條件解釋是: application.properties 或 application.yml 文件中 mybean.enable 爲 true 纔會加載 MyCondition 這個 Bean,若是沒有匹配上也會加載,由於 matchIfMissing = true,默認值是 false。
有時候咱們須要某個 Bean 已經存在應用上下文時纔會加載,那麼咱們會用到 @ConditionalOnBean
註解:
與之相反,有時候咱們須要某個 Bean 不存在於應用上下文時纔會加載,那麼咱們會用到 @ConditionalOnMissingBean
註解
不要嫌我廢話,和上面的同樣,只不過判斷某個類是否存在於 classpath 中,這就不作過多說明了
若是咱們有更復雜的多個配置屬性一塊兒判斷,那麼咱們就能夠用這個表達式了:
只有當兩個屬性都爲 true 的時候才加載 MyModule,到這裏要順便揭曉上一篇文章 你應該知道的 @ConfigurationProperties 註解的使用姿式,這一篇就夠了 靈魂追問 3,其中 :true
就是: 若是沒有爲該屬性設置值,則爲該屬性設置默認值true, 其實這就是@Vaue
註解的規範,一切 SpEL 均可以應用在這裏.
寫到這,我經常使用的已經用完了,還要硬着頭皮介紹其餘幾個內容 😄,開個玩笑,我們繼續:
這個註解和 @ConditionalOnBean 相似,爲了更好的說明該註解的使用 (實際上是 才疏學淺
) ,我只能翻譯一下類的註釋了
只有指定類已存在於 BeanFactory 中,而且能夠肯定單個候選項纔會匹配成功
BeanFactory 存在多個 bean 實例,可是有一個 primary 候選項被指定(一般在類上使用
@Primary
註解),也會匹配成功。實質上,若是自動鏈接具備定義類型的 bean 匹配就會成功目前,條件只是匹配已經被應用上下文處理的 bean 定義,自己來說,強烈建議僅僅在 auto-configuration 類中使用這個條件,若是候選 bean 被另一個 auto-configuration 建立,確保使用該條件的要在其後面運行
若是咱們要加載的 bean 依賴指定資源是否存在於 classpath 中,那麼咱們就可使用這個註解
看到這個 logback.xml 是否是很親切,在咱們引入第三方工具類如 Dozer 等均可以添加相似的開關
接下來的是真冷門,你們有個印象,若是有須要,至少能想到用這些註解實現靈活配置就行了
只有指定的資源經過 JNDI 加載後才加載 bean
只有運行指定版本的 Java 纔會加載 Bean
只有運行在 web 應用裏纔會加載這個 bean
與之相反,在非 web 環境才加載 bean
這個註解冷的我呼吸都要中止了,只有運行在指定的雲平臺上才加載指定的 bean,CloudPlatform 是 org.springframework.boot.cloud
下一個 enum 類型的類,你們能夠打開自行看看:
到此,Spring Boot 爲咱們提供的這 13 個註解就介紹完了,可是沒有結束,下面的一些冷門知識,你須要知道:
若是咱們想多個條件一塊兒應用,而且條件的關係是 and
,咱們只須要在類上使用多個@ConditionalOnXxxx
就能夠了 (你這也叫冷門?) ,固然也能夠繼承 AllNestedConditions
類封裝咱們多個條件
這樣就有了組合 and 條件,只有內部全部條件都知足,才加載指定 bean
若是咱們但願組合的條件是 or
的關係,咱們該怎麼辦呢? 咱們能夠經過繼承 AnyNestedCondition
來完成這一要求,示例代碼和上面同樣,你們自行打開 AnyNestedCondition
類,查看類說明便可
有 and 和 or 就確定有 non(非),咱們能夠經過繼承 NoneNestedConditions
完成這一要求,你們自行查看便可
經過組合方式實現了多條件邏輯應用,咱們須要應用這些組合條件也就要自定義註解,其實文章開頭已經講過了,模仿內置的 13 個註解寫就行了:
只須要經過@Conditional
註解指定咱們自定義的 condition 類就行了,而後應用到你想用的地方就行了
仍是推薦你們看 RabbitMq 的 RabbitAutoConfiguration
類,這個類裏面主流的註解都是用了 (只看這一個類就行了),你們看框架理解學習這些註解是更好的方式:
到這裏,你已經瞭解瞭如何靈活配置 bean,結合以前的文章,相信的定義會更加靈活,但願你們打開 IDE,自行查看這些註解,瞭解更多具體內容
@Configuration
@ConditionalOnClass(MyBean.class)
public class MyConfiguration{
// omitted
}
```## 提升效率工具
![](http://rgyb.sunluomeng.top/%E5%85%AC%E4%BC%97%E8%B4%A6%E5%8F%B7%E6%96%87%E7%AB%A0/%E6%84%9F%E6%83%B3%E4%B8%8E%E6%80%BB%E7%BB%93/_image/2019-06-18/b.png)
--------
## 推薦閱讀
+ [紅黑樹,超強動靜圖詳解,簡單易懂](https://mp.weixin.qq.com/s/ilND8u_8HGSTSrJiMB4X8g)
+ [雙親委派模型:大廠高頻面試題,輕鬆搞定](https://mp.weixin.qq.com/s/Dnr1jLebvBUHnziZzSfcrA)
+ [面試還不知道BeanFactory和ApplicationContext的區別?](https://mp.weixin.qq.com/s/YBQB086ADBjHUmwrFQrWew)
+ [如何設計好的RESTful API](https://mp.weixin.qq.com/s/hR1TqkVzwZ_T8fuMnsM4hQ)
+ [程序猿爲何要看源碼?](https://mp.weixin.qq.com/s/V7h8O6pVFQ-nr_iA2SNqtw)
--------
> ### 歡迎持續關注公衆號:「日拱一兵」
> - 前沿 Java 技術乾貨分享
> - 高效工具彙總
> - 面試問題分析與解答
> - 技術資料領取
**後續會推出 「多線程」以及「ElasticSearch」等連載內容**
> 以讀偵探小說思惟輕鬆趣味學習 Java 技術棧相關知識,本着將複雜問題簡單化,抽象問題具體化和圖形化原則逐步分解技術問題,技術持續更新,請持續關注......
![](http://rgyb.sunluomeng.top/%E5%85%AC%E4%BC%97%E8%B4%A6%E5%8F%B7%E6%96%87%E7%AB%A0/%E6%84%9F%E6%83%B3%E4%B8%8E%E6%80%BB%E7%BB%93/_image/2019-06-18/a%20%281%29.png)複製代碼