1. 程式人生 > 其它 >Spring - 關於條件註解的一些理解

Spring - 關於條件註解的一些理解

目錄

前言

@Conditional是Spring4提供的註解,它可以根據條件判斷是否將Bean註冊到容器中,原始碼如下:

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Conditional {
    Class<? extends Condition>[] value();
}

簡單示例

舉一個簡單的例子,如何根據當前作業系統來進行物件例項化

  • 介面
public interface SystemInter {
    String get();
}
  • 實現類
public class Linux implements SystemInter {
    @Override
    public String get() {
        return "System's Linux";
    }
}

public class Windows implements SystemInter {
    @Override
    public String get() {
        return "System's windows";
    }
}
  • 控制器
public class TestController {
    @Autowired
    private SystemInter systemInter;

    @GetMapping(value = "/system")
    public String getSystem(){
        return systemInter.get();
    }
}

上述程式碼用於表示作業系統的兩個物件,問題來了,如何根據作業系統進行相應的物件例項化,在控制器中注入呢?

這裡就可以用到@Conditional註解,通過實現Condition介面重寫方法來自定義match規則,Condition介面需要實現matches方法,返回true則注入bean,false則不注入。

  • 條件類
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;

public class LinuxCondition implements Condition {
    @Override
    public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
    	// 獲取配置檔案中system.condition的屬性
        String name = conditionContext.getEnvironment().getProperty("system.condition");
        return "linux".equalsIgnoreCase(name);
    }
}

public class WindowsCondition implements Condition {
    @Override
    public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
    	// 獲取配置檔案中system.condition的屬性
        String name = conditionContext.getEnvironment().getProperty("system.condition");
        return "windows".equalsIgnoreCase(name);
    }
}
  • application.properties的配置,配置作業系統為windows
system.condition = windows
  • 建立SystemConfiguration 類,用於配置兩個例項的注入
@Configuration
public class SystemConfiguration {

    @Bean
    @Conditional(LinuxCondition.class)
    public SystemInter linux() {
        return new Linux();
    }

    @Bean
    @Conditional(WindowsCondition.class)
    public SystemInter windows() {
        return new Windows();
    }
}
  • 由上述程式碼可以看出,我們給兩個作業系統物件分別建立的對應的條件類,並通過配置檔案中的system.condition屬性來判斷是否例項化。

  • 訪問介面結果如下,可以看出,我們從配置檔案讀取作業系統型別並例項化了windows物件。

  • 切換application.properties的作業系統配置為linux
system.condition = linux
  • 訪問結果如下:
  • 這是個簡單的例子,卻體現了Spring的策略模式(根據環境或者條件的不同選擇不同的演算法或者策略來完成該功能)

  • 注:以上的示例將@Conditional標註在方法上,而@Conditional標註在類上可以判斷該配置類中的所有Bean是否注入。

內建的條件註解

註解 條件
@ConditionalOnBean 當SpringIoC容器記憶體在指定Bean的條件
@ConditionalOnMissingBean 當SpringIoC容器內不存在指定Bean的條件
@ConditionalOnClass 當SpringIoC容器記憶體在指定Class的條件
@ConditionalOnMissingClass 當SpringIoC容器內不存在指定Class的條件
@ConditionalOnProperty 指定的屬性是否有指定的值
@ConditionalOnResource 類路徑是否有指定的值
@ConditionalOnWebApplication 當前專案是Web專案的條件
@ConditionalOnNotWebApplication 當專案不是Web專案的條件
@ConditionalOnExpression 基於SpEL表示式作為判斷條件
@ConditionalOnJava 基於JVM版本作為判斷條件
@ConditionalOnJndi 在JNDI存在時查詢指定的位置
@ConditionalOnSingleCandidate 當指定Bean在SpringIoC容器內只有一個,或者雖然有多個但是指定首選的Bean
- End -
夢想是鹹魚
關注一下吧
以上為本篇文章的主要內容,希望大家多提意見,如果喜歡記得點個推薦哦 作者:夢想是鹹魚 出處:https://www.cnblogs.com/maggieq8324/ 本文版權歸作者和部落格園共有,歡迎轉載,轉載時保留原作者和文章地址即可。