Spring條件注解@Conditional示例詳解
前言
@Conditional是Spring4新提供的注解,它的作用是根據(jù)某個條件創(chuàng)建特定的Bean,通過實現(xiàn)Condition接口,并重寫matches接口來構(gòu)造判斷條件??偟膩碚f,就是根據(jù)特定條件來控制Bean的創(chuàng)建行為,這樣我們可以利用這個特性進行一些自動的配置。
本文將分為三大部分,@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注解可以用在類和方法上,需要傳入一個實現(xiàn)了Condition接口class數(shù)組。
二、代碼示例
下面將以不同的操作系統(tǒng)為條件,通過實現(xiàn)Condition接口,并重寫其matches方法來構(gòu)造判斷條件。若在Windows系統(tǒng)下運行程序,則輸出列表命令為dir;若在Linux系統(tǒng)下運行程序,則輸出列表命令為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實現(xiàn)類代碼
package com.study.day01;
/**
* @Auther: lifq
* @Description:
*/
public class WindowsService implements ListService {
public String showListCmd() {
return "dir";
}
}
(3).Linux實現(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.運行類
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,運行截圖如下:
運行截圖

@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版本為指定的版本范圍時觸發(fā)實例化。
- @ConditionalOnResource:當類路徑下有指定的資源時觸發(fā)實例化。
- @ConditionalOnJndi:在JNDI存在的條件下觸發(fā)實例化。
- @ConditionalOnSingleCandidate:當指定的Bean在容器中只有一個,或者有多個但是指定了首選的Bean時觸發(fā)實例化。
總結(jié)
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對腳本之家的支持。
相關(guān)文章
解讀靜態(tài)資源訪問static-locations和static-path-pattern
本文主要介紹了Spring Boot中靜態(tài)資源的配置和訪問方式,包括靜態(tài)資源的默認前綴、默認地址、目錄結(jié)構(gòu)、訪問路徑以及靜態(tài)資源處理器的工作原理,通過配置文件和實現(xiàn)`WebMvcConfigurer`接口,可以自定義靜態(tài)資源目錄和訪問前綴2025-01-01
編碼實現(xiàn)從無序鏈表中移除重復項(C和JAVA實例)
如果不能使用臨時緩存,你怎么實現(xiàn)無序鏈表中移除重復項(?C和JAVA實例無序鏈表中移除重復項。2013-10-10
使用Apache Ignite實現(xiàn)Java數(shù)據(jù)網(wǎng)格
今天我們來探討如何使用Apache Ignite來實現(xiàn)Java數(shù)據(jù)網(wǎng)格,Apache Ignite是一個高性能的內(nèi)存計算平臺,它提供了分布式緩存、數(shù)據(jù)網(wǎng)格和計算功能,可以顯著提高大規(guī)模應用的數(shù)據(jù)處理性能,感興趣的小伙伴跟著小編一起來看看吧2024-08-08
Spring Security如何在Servlet中執(zhí)行
這篇文章主要介紹了Spring Security如何在Servlet中執(zhí)行,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2020-04-04

