SpringBoot中condition注解的使用方式
在項(xiàng)目中,有時(shí)會(huì)遇到我們的Configuration、Bean、Service等等的bean組件需要依條件按需加載的情況。
springboot中提供了一系列@Condition* 注解來(lái)處理有條件注入的情況。
說明
Spring4中增加了@Condition annotation, 使用該Annotation之后,在做依賴注入的時(shí)候,會(huì)檢測(cè)是否滿足某個(gè)條件來(lái)決定是否注入某個(gè)類。
springboot基于spring4的這個(gè)注解實(shí)現(xiàn)了多個(gè)用于判斷的條件注解,如果我們?cè)谑褂弥羞@些注解無(wú)法滿足我們的要求還可以使用@Conditional自定義條件注解
常用的條件注解
| 條件注解 | 對(duì)應(yīng)的Condition 處理類 | 處理邏輯 |
|---|---|---|
| @ConditionalOnBean | OnBeanCondition | Spring容器中是否存在對(duì)應(yīng)的實(shí)例??梢酝ㄟ^實(shí)例的類型、類名、注解、昵稱去容器中查找(可以配置從當(dāng)前容器中查找或者父容器中查找或者兩者一起查找) |
| @ConditionalOnClass | OnClassCondition | 類加載器中是否存在對(duì)應(yīng)的類??梢酝ㄟ^Class指定(value屬性)或者Class的全名指定(name屬性)如果是多個(gè)類或者多個(gè)類名的話,關(guān)系是”與”關(guān)系,也就是說這些類或者類名都必須同時(shí)在類加載器中存在 |
| @ConditionalOnExpression | OnExpressionCondition | 判斷SpEL 表達(dá)式是否成立 |
| @ConditionalOnMissingBean | OnBeanCondition | Spring容器中是否缺少對(duì)應(yīng)的實(shí)例??梢酝ㄟ^實(shí)例的類型、類名、注解、昵稱去容器中查找(可以配置從當(dāng)前容器中查找或者父容器中查找或者兩者一起查找) |
| @ConditionalOnMissingClass | OnClassCondition | 跟ConditionalOnClass的處理邏輯一樣,只是條件相反,在類加載器中不存在對(duì)應(yīng)的類 |
| @ConditionalOnProperty | OnPropertyCondition | 應(yīng)用環(huán)境中的屬性是否存在。提供prefix、name、havingValue以及matchIfMissing屬性。prefix表示屬性名的前綴,name是屬性名,havingValue是具體的屬性值,matchIfMissing是個(gè)boolean值,如果屬性不存在,這個(gè)matchIfMissing為true的話,會(huì)繼續(xù)驗(yàn)證下去,否則屬性不存在的話直接就相當(dāng)于匹配不成功 |
| @ConditionalOnResource | OnResourceCondition | 是否存在指定的資源文件。只有一個(gè)屬性resources,是個(gè)String數(shù)組。會(huì)從類加載器中去查詢對(duì)應(yīng)的資源文件是否存在 |
| @ConditionalOnSingleCandidate | OnBeanCondition | Spring容器中是否存在且只存在一個(gè)對(duì)應(yīng)的實(shí)例。只有3個(gè)屬性value、type、search。跟ConditionalOnBean中的這3種屬性值意義一樣 |
| @ConditionalOnWebApplication | OnWebApplicationCondition | 應(yīng)用程序是否是Web程序,沒有提供屬性,只是一個(gè)標(biāo)識(shí)。會(huì)從判斷Web程序特有的類是否存在,環(huán)境是否是Servlet環(huán)境,容器是否是Web容器等 |
舉例
| 例子 | 說明 |
|---|---|
| @ConditionalOnBean(javax.sql.DataSource.class) | Spring容器或者所有父容器中需要存在至少一個(gè)javax.sql.DataSource類的實(shí)例 |
| @ConditionalOnClass({ Configuration.class,FreeMarkerConfigurationFactory.class }) | 類加載器中必須存在Configuration和FreeMarkerConfigurationFactory這兩個(gè)類 |
| @ConditionalOnExpression(“’${server.host}’==’localhost’”) | server.host配置項(xiàng)的值需要是localhost |
| ConditionalOnJava(JavaVersion.EIGHT) | Java版本至少是8 |
| @ConditionalOnMissingBean(value = ErrorController.class, search = SearchStrategy.CURRENT) | Spring當(dāng)前容器中不存在ErrorController類型的bean |
| @ConditionalOnMissingClass(“GenericObjectPool”) | 類加載器中不能存在GenericObjectPool這個(gè)類 |
| @ConditionalOnNotWebApplication | 必須在非Web應(yīng)用下才會(huì)生效 |
| @ConditionalOnProperty(prefix = “spring.aop”, name = “auto”, havingValue = “true”, matchIfMissing = true) | 應(yīng)用程序的環(huán)境中必須有spring.aop.auto這項(xiàng)配置,且它的值是true或者環(huán)境中不存在spring.aop.auto配置(matchIfMissing為true) |
| @ConditionalOnResource(resources=”mybatis.xml”) | 類加載路徑中必須存在mybatis.xml文件 |
| @ConditionalOnSingleCandidate(PlatformTransactionManager.class) | Spring當(dāng)前或父容器中必須存在PlatformTransactionManager這個(gè)類型的實(shí)例,且只有一個(gè)實(shí)例 |
| @ConditionalOnWebApplication | 必須在Web應(yīng)用下才會(huì)生效 |
自定義條件注解
實(shí)現(xiàn)條件化注解我們需要兩個(gè)類
- 自定義注解類
- 定義注解,指定判斷用的條件類
- 條件類
- 實(shí)現(xiàn)org.springframework.context.annotation.Condition接口,定義判斷條件
舉例說明
1.定義注解類MyConditionalOnProperty
要使用注解@Conditional(MyOnPropertyCondition.class),MyOnPropertyCondition為我們要定義的條件類
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
@Documented
@Conditional(MyOnPropertyCondition.class)
public @interface MyConditionalOnProperty {
String value();
String prefix() default "";
String havingValue() default "";
boolean matchIfMissing() default false;
boolean relaxedNames() default true;
//TODO ADD ONE PROPERTY
String havingValue() default "";
}
2.定義條件類:
public class MyOnPropertyCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
Map<String, Object> annotationAttributes = metadata.getAnnotationAttributes(MyConditionalOnProperty.class.getName());
String propertyName = (String) annotationAttributes.get("value");
String value = annotationAttributes.get("havingValue");
String propertyValue = context.getEnvironment().getProperty(propertyName);
if (propertyValue.equalsIgnoreCase(value)) {
return true;
}
return false;
}
}
3.調(diào)用
@Configuration
public class MyConfig {
@Bean
@MyConditionalOnProperty(value = "env",havingValue = "dev")
public Person person(){
log.info("創(chuàng)建Bean");
return new Person();
}
}
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java微信獲取用戶資料報(bào)錯(cuò)48001解決辦法
這篇文章主要介紹了Java微信獲取用戶資料報(bào)錯(cuò)48001的解決辦法,這個(gè)問題大家在工作可能經(jīng)常會(huì)遇到,文中通過示例代碼將解決的辦法介紹的非常詳細(xì),需要的朋友可以參考下2025-09-09
Java數(shù)據(jù)結(jié)構(gòu)之快速冪的實(shí)現(xiàn)
快速冪是用來(lái)解決求冪運(yùn)算的高效方式。本文將詳細(xì)為大家介紹如何利用Java實(shí)現(xiàn)快速冪,以及利用快速冪求解冪運(yùn)算問題,需要的可以參考一下2022-03-03
詳解Maven項(xiàng)目缺少M(fèi)aven Dependencies解決方法總結(jié)
這篇文章主要介紹了詳解Maven項(xiàng)目缺少M(fèi)aven Dependencies解決方法總結(jié),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-11-11
Springboot解決no main manifest attribute錯(cuò)誤
在開發(fā)Springboot項(xiàng)目時(shí),使用java -jar命令運(yùn)行jar包可能出現(xiàn)no main manifest attribute錯(cuò)誤,本文就來(lái)介紹一下該錯(cuò)誤的解決方法,感興趣的可以了解一下2024-09-09
SpringCloud使用Nacos 配置中心實(shí)現(xiàn)配置自動(dòng)刷新功能使用
SpringCloud項(xiàng)目中使用Nacos作為配置中心可以方便開發(fā)及運(yùn)維人員隨時(shí)查看配置信息,及配置共享,并且Nacos支持配置信息實(shí)時(shí)刷新,非常方便,下面給大家介紹SpringCloud使用Nacos配置中心實(shí)現(xiàn)配置自動(dòng)刷新功能使用,感興趣的朋友一起看看吧2025-05-05
springboot 在ftl頁(yè)面上使用shiro標(biāo)簽的實(shí)例代碼
這篇文章主要介紹了springboot 在ftl頁(yè)面上使用shiro標(biāo)簽的實(shí)例代碼,通過文字說明結(jié)合實(shí)例的形式給大家介紹的非常詳細(xì),需要的朋友參考下吧2018-05-05
Java Date與String的相互轉(zhuǎn)換詳解
這篇文章主要介紹了Java Date與String的相互轉(zhuǎn)換詳解的相關(guān)資料,需要的朋友可以參考下2017-02-02

