概述
spring boot 中的 @conditional 注解是一個不太常用到的注解,但確實(shí)非常的有用,我們知道 spring boot 是根據(jù)配置文件中的內(nèi)容,決定是否創(chuàng)建 bean,以及如何創(chuàng)建 bean 到 spring 容器中,而 spring boot 自動化配置的核心控制,就是 @conditional 注解。
@conditional 注解是 spring 4.0 之后出的一個注解,與其搭配的一個接口是 condition,@conditional 注解會根據(jù)具體的條件決定是否創(chuàng)建 bean 到容器中,接下來看看 @conditional 注解的簡單使用。
1. @conditional 和 condition 接口搭配使用
這里需要實(shí)現(xiàn)的功能是,我們根據(jù)配置文件中的具體內(nèi)容,來決定是否創(chuàng)建 bean,首先我們在 application.yml 中加上一個自定義配置:
這里我們決定,這個配置中包含了 product 這個字符串的時候,才創(chuàng)建 bean。product 是我自己隨便創(chuàng)建的一個實(shí)體類,你可以自行創(chuàng)建。
新建一個類 productcondition
,內(nèi)容如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
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 ; } } } |
這個類實(shí)現(xiàn)了 condition 接口,這個接口只有一個方法,我們從配置文件中獲取剛才創(chuàng)建的自定義配置,如果配置中包含了 product 這個字符串,就會返回 true。
接下來創(chuàng)建一個配置類 productconfig,內(nèi)容如下:
1
2
3
4
5
6
7
8
9
10
11
|
@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(); } } |
我們在創(chuàng)建的 bean 方法前面加上了 @conditional 注解,判斷的標(biāo)準(zhǔn)是剛才的 productcondition,如果是 true,則創(chuàng)建 bean,否則不創(chuàng)建。我們寫一個測試類,來測試一下 bean 是否被創(chuàng)建了。測試代碼如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
@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( "創(chuàng)建了 bean : " + product.tostring()); } } catch (exception e){ log.info( "發(fā)生異常,{}" , e.getmessage()); system.out.println( "沒有創(chuàng)建 bean" ); } } } |
運(yùn)行測試代碼,發(fā)現(xiàn) bean 已經(jīng)創(chuàng)建了:
如果把 application.yml 中的配置改一下,不包含 product 這個字符串,那么返回的是 false,bean 則不會被創(chuàng)建,你可以試一下。
2. @conditionalonclass 的使用
這個注解的屬性可以跟上一個類的完整路徑或者是類的 class 對象,如果類存在,則會創(chuàng)建 bean,例如下面的例子:
1
2
3
4
5
6
7
8
9
10
11
12
|
@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(); } } |
這個路徑下面的實(shí)體類 product 是存在的,所以會創(chuàng)建 bean,如果是一個不存在的類,則不會創(chuàng)建。
3. @conditionalonproperty 的使用
這個注解可以直接從配置文件中獲取屬性,然后做為是否創(chuàng)建 bean 的依據(jù)。例如我們在 application.yml 中添加一個自定義配置:
productconfig 類的內(nèi)容是這樣的:
1
2
3
4
5
6
7
8
9
10
11
12
|
@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 注解,從文件中讀取配置,因?yàn)槲覀冊O(shè)置的是 true,所以這個 bean 會被創(chuàng)建,如果設(shè)置成 false,則 bean 不會被創(chuàng)建,你可以自己試一下。根據(jù)這個特性,我們可以給一些特定的配置加上一個開關(guān),非常方便控制。
這里我只是列舉了幾個常用的注解,你可以查看官方文檔,里面有更詳細(xì)的說明:
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持服務(wù)器之家。
原文鏈接:https://segmentfault.com/a/1190000018777937