Spring使用@Conditional進行條件裝配的實現
在spring中有些bean需要滿足某些環(huán)境條件才創(chuàng)建某個bean,這個時候可以在bean定義上使用@Conditional注解來修飾。@Conditional需要指定一個條件類,這個類不需實現Condition接口并且實現其matches方法。只有當matches方法返回true時才創(chuàng)建當前bean。
例如下面定義一個bean只有當當前jdk版本大于等于8時才創(chuàng)建該bean。
bean定義這里寫的很簡單,
@Service @Conditional(Java8Condition.class) public class ConditionService { }
看Java8Condition條件類
public class Java8Condition implements Condition { @Override public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { return JavaVersion.getJavaVersion().isEqualOrNewerThan(JavaVersion.EIGHT); } }
這里判斷當前java的版本,如果大于等于8則返回true,ConditionService會被創(chuàng)建成bean,否則不會創(chuàng)建該bean。
Condition的matches方法有兩個入參,context和metadata。從context可以獲取beanFactory和environment信息,從metadata可以獲取當前bean上所有注解配置信息。通過這兩個參數可以獲取到很多信息了,這里就可以根據上下文來進行判斷。不如beanFacotry是否有某個bean,當前環(huán)境的profile信息,某個屬性的配置信息等等。
看到這里你是否想到了些什么,沒錯就是springboot的自動條件裝配。springboot對@Conditional進行了擴展,在org.springframework.boot.autoconfigure.condition包下有很多封裝好的條件注解。如
ConditionalOnBean:某個bean存在時
ConditionalOnClass: 某個class存在時
ConditionalOnExpression: SpEL表達式成立時
ConditionalOnJava: java環(huán)境版本
ConditionalOnProperty: 某個property值是多少時
ConditionalOnMissingBean: 某個bean不存在時
等等還有很多。這就明白為什么有些bean我們沒有顯示聲明可以直接拿來注入使用了吧。
condition的擴展
雖然springboot也封裝了很多場景的condition注解,但是難免有時候還是有些業(yè)務場景可能需要自定義conditon。這里就來以判斷上下文某個屬性值來擴展condition。
最開始看到@Conditional注解是只有一個Condition類來指定出來條件判斷邏輯,沒有額外的配置項。這里要判斷某個property必須要指定property的key和value,所以第一步先自定義一個注解
@Retention(RetentionPolicy.RUNTIME) @Target({ ElementType.TYPE, ElementType.METHOD }) @Conditional(PropertyConditionMatcher.class) public @interface MyPropertyCondition { String name(); String value(); }
這里自定義注解PropertyConditionMatcher兩個屬性name用來指定property的key,value用來指定property的value。除此之外我們自定義的注解還用@Conditional來修飾,這樣才能我們自定義的注解才能被當作@Conditional來處理。然后來看我們的condition處理類PropertyConditionMatcher。
public class PropertyConditionMatcher implements Condition { @Override public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { Map<String, Object> annotationAttributes = metadata.getAnnotationAttributes(MyPropertyCondition.class.getName()); String propName = (String) annotationAttributes.get("name"); Object value = annotationAttributes.get("value"); String property = context.getEnvironment().getProperty(propName); if(property != null && property.equals(value)){ return true; } return false; } }
這里還是實現了Condition接口。然后首先從metadata中獲取配置的property名稱和value,然后從context的Environment根據前面的property名獲取當前環(huán)境對應值,兩個value進行對比相等來判斷是否滿足條件。
然后具體條件bean上配置MyPropertyCondition。
@Service @MyPropertyCondition(name = "condation.enable",value = "true") public class ConditionService { }
這樣當我們在properties文件中配置condation.enable=true時,ConditionService就會創(chuàng)建為一個bean,否則不會創(chuàng)建。
以上就是Spring使用@Conditional進行條件裝配的實現的詳細內容,更多關于Spring @Conditional條件裝配的資料請關注腳本之家其它相關文章!
相關文章
Springboot之restTemplate配置及使用方式
這篇文章主要介紹了Springboot之restTemplate配置及使用方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2025-04-04Eclipse可視化插件WindowBuilder的安裝方法
這篇文章主要介紹了Eclipse可視化插件WindowBuilder的安裝方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-06-06教你通過B+Tree平衡多叉樹理解InnoDB引擎的聚集和非聚集索引
大家都知道B+Tree是從二叉樹演化而來,在這之前我們來先了解二叉樹、平衡二叉樹、平衡多叉樹,這篇文章主要介紹了通過B+Tree平衡多叉樹理解InnoDB引擎的聚集和非聚集索引,需要的朋友可以參考下2022-01-01