最近在寫(xiě)一個(gè)“啟動(dòng)時(shí)導(dǎo)入數(shù)據(jù)”的小功能。實(shí)現(xiàn)很簡(jiǎn)單, CommandLineRunner會(huì)在SpringBoot啟動(dòng)時(shí)運(yùn)行智政,第一版長(zhǎng)這樣:
@Order(1)
@Component
public class DictionaryInitializer implements CommandLineRunner {
@Override
public void run(String... args) throws Exception {
//do import dictionary
}
}
自然的,我們希望這個(gè)可配置化急凰,只在需要的時(shí)候運(yùn)行女仰。我們使用@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
隨著功能的迭代,我們又更多類(lèi)似的導(dǎo)入功能抡锈,例如導(dǎo)入Product和Parameter疾忍。依樣畫(huà)葫蘆,application.properties中多了相似的配置
app.initialize.dictionary=true
app.initialize.product=true
app.initialize.parameter=true
進(jìn)一步優(yōu)化床三,隨著導(dǎo)入功能的增多一罩。我們可能需要一個(gè)一鍵導(dǎo)入的功能,同時(shí)也要保留原來(lái)的功能撇簿。
app.initialize.all=true
這個(gè)有點(diǎn)麻煩聂渊,涉及到多個(gè)條件的組合叶眉。ConditionalOnProperty是支持 “多個(gè)條件邏輯與”的
@ConditionalOnProperty(name={"app.initialize.dictionary","app.initialize.all"}, havingValue="true")
當(dāng)然這個(gè)不符合我們的要求舆床,我們需要“邏輯或”
首先一個(gè)類(lèi)是不能標(biāo)注多個(gè)相同annotation的鸭蛙,編譯通不過(guò)耕漱。
@Order(1)
@Component
??@ConditionalOnProperty(name="app.initialize.dictionary", havingValue="true")
??@ConditionalOnProperty(name="app.initialize.all", havingValue="true")
public class DictionaryInitializer implements CommandLineRunner
@ConditionalOnProperty 本身也并沒(méi)有這樣的功能
一種繁瑣的做法潘鲫,是自定義條件眷柔,繼承AnyNestedCondition
class DicOrAllCondition extends AnyNestedCondition {
public DicOrAllCondition() {
super(ConfigurationPhase.PARSE_CONFIGURATION);
}
@ConditionalOnProperty(name = "app.initialize.dictionary", value = "true")
static class DicCondition {
}
@ConditionalOnProperty(name = "app.initialize.all", value = "true")
static class AllCondition {
}
}
@Order(1)
@Component
@Conditional(DicOrAllCondition.class)
public class DictionaryInitializer implements CommandLineRunner{}
還有一種比較靈活的方式是使用@ConditionalOnExpression寫(xiě)一個(gè)表達(dá)式
@Order(1)
@Component
@ConditionalOnExpression("${app.initialize.dictionary:false} || ${app.initialize.all:false}")
public class DictionaryInitializer implements CommandLineRunner{}
精益無(wú)止境辅甥,其實(shí)還有更靈活的配置方式:除了dictionary其他都導(dǎo)入:
app.initialize.all=true
app.initialize.dictionary=false
換種說(shuō)法就是:如果局部有配置狡忙,則按局部配置處理洗做。如果局部沒(méi)配置弓叛,則按全局配置處理。如果全局诚纸、局部都沒(méi)配置撰筷,則默認(rèn)不導(dǎo)入。這里可以利用“默認(rèn)值”嵌套表達(dá)式實(shí)現(xiàn)畦徘。
@ConditionalOnExpression("${app.initialize.dictionary:${app.initialize.all:false}}")
最后編輯于 :2019.01.25 09:50:47
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者