Spring條件注解@Conditional


@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

關注下方公眾號即可免費領取:

Java碎碎念公眾號

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM