SpringBoot中的條件注入@Conditional

@Conditional 是spring4.0中引入的的,不是springBoot特有的,只不過在springBoot中做了優化,不要被文章的標題所誤導!
我們都知道springBoot之所以可以實現快速開發是因爲它有自動配置,而實現自動化配置的核心就是@Conditional。而@Conditional在日常開發中不經常使用,但是它的地位是舉足輕重的。
@Conditional顧名思義,就是條件註解,根據滿足某一個特定的條件創建一個特定的Bean
源碼如下:

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Conditional {

	/**
	 * All {@link Condition}s that must {@linkplain Condition#matches match}
	 * in order for the component to be registered.
	 */
	Class<? extends Condition>[] value();

}
@FunctionalInterface
public interface Condition {

	/**
	 * Determine if the condition matches.
	 * @param context the condition context
	 * @param metadata metadata of the {@link org.springframework.core.type.AnnotationMetadata class}
	 * or {@link org.springframework.core.type.MethodMetadata method} being checked
	 * @return {@code true} if the condition matches and the component can be registered,
	 * or {@code false} to veto the annotated component's registration
	 */
	boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata);

}

Condition是一個接口,實現這個接口重寫matches 方法,其返回值是一個boolean 類型,從而決定是否需要加載Bean,當爲true時滿足條件,爲false時不滿足條件!

案例說明:根據開發人員會的技能讓其做相應的開發!

  1. 定義一個技能接口,裏面有一個技能類型的方法
public interface Skills {
	
	public String skillType();

}

2.定義 Java技能

public class JavaSkill implements Skills {

	@Override
	public String skillType() {
		// TODO Auto-generated method stub
		return "做java開發!";
	}

}

3.定義 Python技能

public class PythonSkill implements Skills {

	@Override
	public String skillType() {
		// TODO Auto-generated method stub
		return "做Python開發!";
	}

}
  1. 定義 JavaSkillCondition 用於條件判斷
public class JavaSkillCondition implements Condition{

	@Override
	public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
		// 做其他判斷
		
		return true;
	}

}
  1. 定義 PythonSkillCondition 用於條件判斷
public class PythonSkillCondition implements Condition{

	@Override
	public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
		// 做其他判斷
		
		return false;
	}

}
  1. 定義 SkillConfig 滿足相應技能 注入相應Bean
@Configuration
public class SkillConfig {
	
	@Bean("Skills")
	@Conditional(JavaSkillCondition.class)
	public Skills getJavaSkill() {
		
		return new JavaSkill();
	}
	
	@Bean("Skills")
	@Conditional(PythonSkillCondition.class)
	public Skills getPythonSkill() {
		
		return new PythonSkill();
	}

}

定義了一個技能接口 Skills,接口中有一個方法 skillType,兩個實現類(JavaSkill和PythonSkill)實現這個接口,接着定義了滿足注入JavaSkill 的條件JavaSkillCondition和滿足注入PythonSkill的條件PythonSkillCondition,最後配置了一個configuration來實現配置Bean。值得注意的是:
1. 兩個 Bean 的名字都爲Skills ,因爲兩個Bean的返回值都是起父類對象Skills ,當然可以修改成任意的值,但要和獲取的getBean的參數保持一致
2. 每個 Bean 上都有一個 @Conditional 註解,當 @Conditional 註解中配置的條件類的 matches 方法返回值爲 true 時,對應的 Bean 就會生效!

測試:

@SpringBootApplication
public class AppNettyClient {

	public static void main(String[] args) {
		ConfigurableApplicationContext application= SpringApplication.run(AppNettyClient.class, args);
		Skills skills = (Skills)application.getBean("Skills");
		System.out.println(skills.skillType());
	}

}

再次切換matches 方法返回值進行測試,控制檯會輸出不同的結果!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章