Spring Boot通過@ConditionalOnProperty,@ConditionalOnExpression來控制Configuration是否生效

發(fā)現(xiàn)了Spring boot中有個注解@ConditionalOnProperty,這個注解能夠控制某個configuration是否生效。具體操作是通過其兩個屬性name以及havingValue來實現(xiàn)的,其中name用來從application.properties中讀取某個屬性值,如果該值為空,則返回false;如果值不為空,則將該值與havingValue指定的值進行比較,如果一樣則返回true;否則返回false。如果返回值為false,則該configuration不生效;為true則生效。

也可以在 @Service 注解一起使用. 這樣service層就可以不生效

//在application.properties配置"mf.assert",對應(yīng)的值為true
@Configuration
//如果synchronize在配置文件中并且值為true
@ConditionalOnProperty(prefix="mf",name = "assert", havingValue = "true")
public class SecondDatasourceConfig {

    @Bean(name = "SecondDataSource")
    @Qualifier("SecondDataSource")
    @ConfigurationProperties(prefix = "spring.second.datasource")
    public DataSource jwcDataSource() {
        return DataSourceBuilder.create().build();
    }
}

一些復(fù)雜應(yīng)用

最近在寫一個“啟動時導(dǎo)入數(shù)據(jù)”的小功能。實現(xiàn)很簡單, CommandLineRunner會在SpringBoot啟動時運行,第一版長這樣:

Order(1)
@Component
public class DictionaryInitializer implements CommandLineRunner {
    @Override
    public void run(String... args) throws Exception {
          //do import dictionary
    }
}

自然的,我們希望這個可配置化,只在需要的時候運行。我們使用@ConditionalOnProperty

@Order(1)
@Component
@ConditionalOnProperty(name="app.initialize.dictionary", havingValue="true")
public class DictionaryInitializer implements CommandLineRunner {
    @Override
    public void run(String... args) throws Exception {
          //do import dictionary
    }
}

然后在application.properties中加入

app.initialize.dictionary=true

隨著功能的迭代,我們又更多類似的導(dǎo)入功能,例如導(dǎo)入Product和Parameter。依樣畫葫蘆,application.properties中多了相似的配置
這個有點麻煩,涉及到多個條件的組合。ConditionalOnProperty是支持 “多個條件邏輯與”的

還有一種比較靈活的方式是使用@ConditionalOnExpression寫一個表達式

@Order(1)
@Component
@ConditionalOnExpression("${app.initialize.dictionary:false} || ${app.initialize.all:false}")
public class DictionaryInitializer implements CommandLineRunner{}

精益無止境,其實還有更靈活的配置方式:除了dictionary其他都導(dǎo)入:

app.initialize.all=true
app.initialize.dictionary=false

換種說法就是:如果局部有配置,則按局部配置處理。如果局部沒配置,則按全局配置處理。如果全局、局部都沒配置,則默認不導(dǎo)入。這里可以利用“默認值”嵌套表達式實現(xiàn)

@ConditionalOnExpression("${app.initialize.dictionary:${app.initialize.all:false}}")

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容