Spring條件注解@Conditional示例詳解
前言
@Conditional是Spring4新提供的注解,它的作用是根據(jù)某個(gè)條件創(chuàng)建特定的Bean,通過(guò)實(shí)現(xiàn)Condition接口,并重寫(xiě)matches接口來(lái)構(gòu)造判斷條件。總的來(lái)說(shuō),就是根據(jù)特定條件來(lái)控制Bean的創(chuàng)建行為,這樣我們可以利用這個(gè)特性進(jìn)行一些自動(dòng)的配置。
本文將分為三大部分,@Conditional源碼的介紹、Condition的使用示例和@Conditional的擴(kuò)展注解的介紹。
一、@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注解可以用在類和方法上,需要傳入一個(gè)實(shí)現(xiàn)了Condition接口class數(shù)組。
二、代碼示例
下面將以不同的操作系統(tǒng)為條件,通過(guò)實(shí)現(xiàn)Condition接口,并重寫(xiě)其matches方法來(lái)構(gòu)造判斷條件。若在Windows系統(tǒng)下運(yùn)行程序,則輸出列表命令為dir;若在Linux系統(tǒng)下運(yùn)行程序,則輸出列表命令為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.不同系統(tǒng)下的Bean的類
(1).接口代碼
package com.study.day01; import org.springframework.stereotype.Service; /** * @Auther: lifq * @Description: */ public interface ListService { public String showListCmd(); }
(2).Windows實(shí)現(xiàn)類代碼
package com.study.day01; /** * @Auther: lifq * @Description: */ public class WindowsService implements ListService { public String showListCmd() { return "dir"; } }
(3).Linux實(shí)現(xiàn)類代碼
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.運(yùn)行類
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") + "系統(tǒng)下的列表命令為:" + listService.showListCmd()); } }
我的是Windows操作系統(tǒng),輸出結(jié)果為dir,運(yùn)行截圖如下:
運(yùn)行截圖
@Conditional注解例子演示完成,有問(wèn)題歡迎留言溝通哦!
完整源碼地址:https://github.com/suisui2019/springboot-study
三、@Conditional的擴(kuò)展注解
- @ConditionalOnBean:僅僅在當(dāng)前上下文中存在某個(gè)對(duì)象時(shí),才會(huì)實(shí)例化一個(gè)Bean。
- @ConditionalOnClass:某個(gè)class位于類路徑上,才會(huì)實(shí)例化一個(gè)Bean。
- @ConditionalOnExpression:當(dāng)表達(dá)式為true的時(shí)候,才會(huì)實(shí)例化一個(gè)Bean。
- @ConditionalOnMissingBean:僅僅在當(dāng)前上下文中不存在某個(gè)對(duì)象時(shí),才會(huì)實(shí)例化一個(gè)Bean。
- @ConditionalOnMissingClass:某個(gè)class類路徑上不存在的時(shí)候,才會(huì)實(shí)例化一個(gè)Bean。
- @ConditionalOnNotWebApplication:不是web應(yīng)用,才會(huì)實(shí)例化一個(gè)Bean。
- @ConditionalOnBean:當(dāng)容器中有指定Bean的條件下進(jìn)行實(shí)例化。
- @ConditionalOnMissingBean:當(dāng)容器里沒(méi)有指定Bean的條件下進(jìn)行實(shí)例化。
- @ConditionalOnClass:當(dāng)classpath類路徑下有指定類的條件下進(jìn)行實(shí)例化。
- @ConditionalOnMissingClass:當(dāng)類路徑下沒(méi)有指定類的條件下進(jìn)行實(shí)例化。
- @ConditionalOnWebApplication:當(dāng)項(xiàng)目是一個(gè)Web項(xiàng)目時(shí)進(jìn)行實(shí)例化。
- @ConditionalOnNotWebApplication:當(dāng)項(xiàng)目不是一個(gè)Web項(xiàng)目時(shí)進(jìn)行實(shí)例化。
- @ConditionalOnProperty:當(dāng)指定的屬性有指定的值時(shí)進(jìn)行實(shí)例化。
- @ConditionalOnExpression:基于SpEL表達(dá)式的條件判斷。
- @ConditionalOnJava:當(dāng)JVM版本為指定的版本范圍時(shí)觸發(fā)實(shí)例化。
- @ConditionalOnResource:當(dāng)類路徑下有指定的資源時(shí)觸發(fā)實(shí)例化。
- @ConditionalOnJndi:在JNDI存在的條件下觸發(fā)實(shí)例化。
- @ConditionalOnSingleCandidate:當(dāng)指定的Bean在容器中只有一個(gè),或者有多個(gè)但是指定了首選的Bean時(shí)觸發(fā)實(shí)例化。
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)腳本之家的支持。
相關(guān)文章
Spring Bean Scope 有狀態(tài)的Bean與無(wú)狀態(tài)的Bean
這篇文章主要介紹了Spring Bean Scope 有狀態(tài)的Bean與無(wú)狀態(tài)的Bean,每個(gè)用戶有自己特有的一個(gè)實(shí)例,在用戶的生存期內(nèi),bean保持了用戶的信息,下面來(lái)了解有狀態(tài)和無(wú)狀態(tài)的區(qū)別吧2022-01-01SpringBoot?spring.factories加載時(shí)機(jī)分析
這篇文章主要為大家介紹了SpringBoot?spring.factories加載時(shí)機(jī)分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-03-03mybatis-plus自定義排序的實(shí)現(xiàn)
本文主要介紹了mybatis-plus自定義排序的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-01-01Java中List與數(shù)組之間的相互轉(zhuǎn)換
在日常Java學(xué)習(xí)或項(xiàng)目開(kāi)發(fā)中,經(jīng)常會(huì)遇到需要int[]數(shù)組和List列表相互轉(zhuǎn)換的場(chǎng)景,然而往往一時(shí)難以想到有哪些方法,最后可能會(huì)使用暴力逐個(gè)轉(zhuǎn)換法,往往不是我們所滿意的,下面這篇文章主要給大家介紹了關(guān)于Java中List與數(shù)組之間的相互轉(zhuǎn)換,需要的朋友可以參考下2023-05-05Java Socket使用加密協(xié)議進(jìn)行傳輸對(duì)象的方法
這篇文章主要介紹了Java Socket使用加密協(xié)議進(jìn)行傳輸對(duì)象的方法,結(jié)合實(shí)例形式分析了java socket加密協(xié)議相關(guān)接口與類的調(diào)用方法,以及服務(wù)器、客戶端實(shí)現(xiàn)技巧,需要的朋友可以參考下2017-06-06Java Spring @Autowired的這些騷操作,你都知道嗎
這篇文章主要介紹了徹底搞明白Spring中的自動(dòng)裝配和Autowired注解的使用,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2021-09-09在java中使用SPI創(chuàng)建可擴(kuò)展的應(yīng)用程序操作
這篇文章主要介紹了在java中使用SPI創(chuàng)建可擴(kuò)展的應(yīng)用程序操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-09-09