淺談 Spring Boot 中的 @Conditional 註解
概述
Spring boot 中的 @Conditional 註解是一個不太常用到的註解,但確實非常的有用,我們知道 Spring Boot 是根據配置檔案中的內容,決定是否建立 bean,以及如何建立 bean 到 Spring 容器中,而 Spring boot 自動化配置的核心控制,就是 @Conditional 註解。
@Conditional 註解是 Spring 4.0 之後出的一個註解,與其搭配的一個介面是 Condition,@Conditional 註解會根據具體的條件決定是否建立 bean 到容器中,接下來看看 @Conditional 註解的簡單使用。
1. @Conditional 和 Condition 介面搭配使用
這裡需要實現的功能是,我們根據配置檔案中的具體內容,來決定是否建立 bean,首先我們在 application.yml 中加上一個自定義配置:
這裡我們決定,這個配置中包含了 product 這個字串的時候,才建立 bean。Product 是我自己隨便建立的一個實體類,你可以自行建立。
新建一個類 ProductCondition
,內容如下:
public class ProductCondition implements Condition { @Override public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) { //從配置檔案中獲取屬性 String property = conditionContext.getEnvironment().getProperty("create.bean"); if (property != null){ return property.contains("product"); } else { return false; } } }
這個類實現了 Condition 介面,這個介面只有一個方法,我們從配置檔案中獲取剛才建立的自定義配置,如果配置中包含了 product 這個字串,就會返回 true。
接下來建立一個配置類 ProductConfig,內容如下:
@Configuration public class ProductConfig { @Conditional(ProductCondition.class) @Bean(name = "product") public Product createProd(){ return Product.builder().id(12312).categoryId(12). productName("Mac Book Pro").productImg("prod.png") .productPrice(18000).build(); } }
我們在建立的 bean 方法前面加上了 @Conditional 註解,判斷的標準是剛才的 ProductCondition,如果是 true,則建立 bean,否則不建立。我們寫一個測試類,來測試一下 bean 是否被建立了。測試程式碼如下:
@Slf4j @SpringBootTest @RunWith(SpringRunner.class) public class ProductConfigTest { @Test public void createProd() { try { Product product = SpringContextUtil.getBean("product", Product.class); if (product != null){ System.out.println("建立了 bean : " + product.toString()); } } catch (Exception e){ log.info("發生異常,{}", e.getMessage()); System.out.println("沒有建立 bean"); } } }
執行測試程式碼,發現 bean 已經建立了:
如果把 application.yml 中的配置改一下,不包含 product 這個字串,那麼返回的是 false,bean 則不會被建立,你可以試一下。
2. @ConditionalOnClass 的使用
這個註解的屬性可以跟上一個類的完整路徑或者是類的 Class 物件,如果類存在,則會建立 bean,例如下面的例子:
@Configuration public class ProductConfig { @ConditionalOnClass(name = "com.roseduan.demo.entity.Product") @Bean(name = "product") public Product createProd(){ return Product.builder().id(12312).categoryId(12). productName("Mac Book Pro").productImg("prod.png") .productPrice(18000).build(); } }
這個路徑下面的實體類 Product 是存在的,所以會建立 bean,如果是一個不存在的類,則不會建立。
3. @ConditionalOnProperty 的使用
這個註解可以直接從配置檔案中獲取屬性,然後做為是否建立 bean 的依據。例如我們在 application.yml 中新增一個自定義配置:
ProductConfig 類的內容是這樣的:
@Configuration public class ProductConfig { @ConditionalOnProperty(value = "create.product.bean") @Bean(name = "product") public Product createProd(){ return Product.builder().id(12312).categoryId(12). productName("Mac Book Pro").productImg("prod.png") .productPrice(18000).build(); } }
這裡使用了 @ConditionalOnProperty 註解,從檔案中讀取配置,因為我們設定的是 true,所以這個 bean 會被建立,如果設定成 false,則 bean 不會被建立,你可以自己試一下。根據這個特性,我們可以給一些特定的配置加上一個開關,非常方便控制。
這裡我只是列舉了幾個常用的註解,你可以檢視官方文件,裡面有更詳細的說明:
參考文件: Spring Boot 官網文件