@Conditional是Spring4新提供的註解,它的作用是根據某個條件建立特定的Bean,通過實現Condition介面,並重寫matches介面來構造判斷條件。總的來說,就是根據特定條件來控制Bean的建立行為,這樣我們可以利用這個特性進行一些自動的配置。
本文將分為三大部分,@Conditional原始碼的介紹、Condition的使用示例和@Conditional的擴充套件註解的介紹。
一、@Conditional的原始碼
@Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Conditional { /** * All {@link Condition Conditions} that must {@linkplain Condition#matches match} * in order for the component to be registered. */ Class<? extends Condition>[] value(); }
從原始碼中可以看到,@Conditional註解可以用在類和方法上,需要傳入一個實現了Condition介面class陣列。
二、程式碼示例
下面將以不同的作業系統為條件,通過實現Condition介面,並重寫其matches方法來構造判斷條件。若在Windows系統下執行程式,則輸出列表命令為dir;若在Linux系統下執行程式,則輸出列表命令為ls。
1.判斷條件類的定義
(1).判斷Windows的條件
package com.study.day01; import org.springframework.context.annotation.Condition; import org.springframework.context.annotation.ConditionContext; import org.springframework.core.type.AnnotatedTypeMetadata; /** * @Auther: lifq * @Description: */ public class WindowsCondition implements Condition { public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { return context.getEnvironment().getProperty("os.name").contains("Windows"); } }
(2).判斷Linux的條件
package com.study.day01; import org.springframework.context.annotation.Condition; import org.springframework.context.annotation.ConditionContext; import org.springframework.core.type.AnnotatedTypeMetadata; /** * @Auther: lifq * @Description: */ public class LinuxCondition implements Condition { public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { return context.getEnvironment().getProperty("os.name").contains("Linux"); } }
2.不同系統下的Bean的類
(1).介面程式碼
package com.study.day01; import org.springframework.stereotype.Service; /** * @Auther: lifq * @Description: */ public interface ListService { public String showListCmd(); }
(2).Windows實現類程式碼
package com.study.day01; /** * @Auther: lifq * @Description: */ public class WindowsService implements ListService { public String showListCmd() { return "dir"; } }
(3).Linux實現類程式碼
package com.study.day01; /** * @Auther: lifq * @Description: */ public class LinuxService implements ListService { public String showListCmd() { return "ls"; } }
3.配置類
package com.study.day01; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; /** * @Auther: lifq * @Description: */ @Configuration public class Config { @Bean @Conditional(WindowsCondition.class) public ListService window() { return new WindowsService(); } @Bean @Conditional(LinuxCondition.class) public ListService linux() { return new LinuxService(); } }
4.執行類
package com.study.day01; import org.springframework.context.annotation.AnnotationConfigApplicationContext; /** * @Auther: lifq * @Description: */ public class Main01 { public static void main (String []args) { AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(Config.class); ListService listService = applicationContext.getBean(ListService.class); System.out.println(applicationContext.getEnvironment().getProperty("os.name") + "系統下的列表命令為:" + listService.showListCmd()); } }
我的是Windows作業系統,輸出結果為dir,執行截圖如下:
執行截圖
@Conditional註解例子演示完成,有問題歡迎留言溝通哦!
完整原始碼地址:https://github.com/suisui2019/springboot-study
三、@Conditional的擴充套件註解
@ConditionalOnBean:僅僅在當前上下文中存在某個物件時,才會例項化一個Bean。
@ConditionalOnClass:某個class位於類路徑上,才會例項化一個Bean。
@ConditionalOnExpression:當表示式為true的時候,才會例項化一個Bean。
@ConditionalOnMissingBean:僅僅在當前上下文中不存在某個物件時,才會例項化一個Bean。
@ConditionalOnMissingClass:某個class類路徑上不存在的時候,才會例項化一個Bean。
@ConditionalOnNotWebApplication:不是web應用,才會例項化一個Bean。
@ConditionalOnBean:當容器中有指定Bean的條件下進行例項化。
@ConditionalOnMissingBean:當容器裡沒有指定Bean的條件下進行例項化。
@ConditionalOnClass:當classpath類路徑下有指定類的條件下進行例項化。
@ConditionalOnMissingClass:當類路徑下沒有指定類的條件下進行例項化。
@ConditionalOnWebApplication:當專案是一個Web專案時進行例項化。
@ConditionalOnNotWebApplication:當專案不是一個Web專案時進行例項化。
@ConditionalOnProperty:當指定的屬性有指定的值時進行例項化。
@ConditionalOnExpression:基於SpEL表示式的條件判斷。
@ConditionalOnJava:當JVM版本為指定的版本範圍時觸發例項化。
@ConditionalOnResource:當類路徑下有指定的資源時觸發例項化。
@ConditionalOnJndi:在JNDI存在的條件下觸發例項化。
@ConditionalOnSingleCandidate:當指定的Bean在容器中只有一個,或者有多個但是指定了首選的Bean時觸發例項化。
推薦閱讀
1.Spring Boot入門-快速搭建web專案
2.Spring Boot 2.X 整合Redis
3.Spring Boot 2.X 如何優雅的解決跨域問題?
4.Spring Boot 2.X 如何新增攔截器?
5.Spring Boot 2.X 整合spring session實現session共享
6.Redis Cluster搭建高可用Redis伺服器叢集
7.為什麼單執行緒的Redis這麼快?
8.一篇文章搞定SpringMVC引數繫結
9.SpringMVC+Mybatis 如何配置多個資料來源並切換?
限時領取免費Java相關資料,涵蓋了Java、Redis、MongoDB、MySQL、Zookeeper、Spring Cloud、Dubbo/Kafka、Hadoop、Hbase、Flink等高併發分散式、大資料、機器學習等技術。
資料傳送門: https://mp.weixin.qq.com/s/u2b_NVNuMuAPE0w4lc45fw
關注下方公眾號即可免費領取: