本文主要介紹spring和springboot提供的幾個(gè)annotation和interface實(shí)現(xiàn)符合幾種既定條件或自定義條件下的autoconfigure
一、spring實(shí)現(xiàn)自定義條件下的autoconfigure
spring為我們提供了@Conditional和Condition.class搭配使用的方式實(shí)現(xiàn)自定義條件下的autoconfigure,源碼如下:


編寫一個(gè)class,繼承Condition這個(gè)接口,重寫matches()方法,當(dāng)該方法返回true時(shí)auto-configure生效,反之不生效,代碼如下
public class MyCondition implements Condition {
@Override
public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
//what.is.you.name的value寫在application.properties中
String name = conditionContext.getEnvironment().getProperty("what.is.you.name");
return "bamu".equals(name);
}
}
matches方法提供了ConditionContext和AnnotatedTypeMetadata兩個(gè)參數(shù),我們可以通過ConditionContext獲取到編寫在application-xxx.properties中的配置信息。
application.properties配置文件內(nèi)容如下:注意我們現(xiàn)在定義的value和Mycondition中定義的不同
what.is.you.name=heiheihei
編寫一個(gè)Config類,其中runnableBean1、runnableBean3需要滿足我們以上自定義的條件才允許被自動(dòng)注入。
@SpringBootConfiguration
public class ConditionBeanConfig {
@Bean
@Conditional(MyCondition.class)
public Runnable runnableBean1() {
return () ->{};
}
@Bean
public Runnable runnableBean2() {
return () ->{};
}
@Bean
@Conditional(MyCondition.class)
public Runnable runnableBean3() {
return () ->{};
}
}
執(zhí)行main方法結(jié)果如下:
@SpringBootApplication
public class BlogApplication {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(BlogApplication.class, args);
String[] beans = context.getBeanNamesForType(Runnable.class);
System.out.println(Arrays.toString(beans));
context.close();
}
}

修改application.properties,將value改為
MyCondition.class中定義的值后執(zhí)行結(jié)果如下:

我們發(fā)現(xiàn),自定義的MyCondition已經(jīng)生效。細(xì)心的讀者可能發(fā)現(xiàn),@Conditional注解源碼中傳入的value是一個(gè)數(shù)組
Class<? extends Condition>[] value();,所以我們可以傳入多個(gè)自定義Condition,例如@Condition({MyCondition.class, YourCondition.class})
另外,@Conditianal不僅可以寫在方法上,還可以寫在configuration.class上,這樣該類中的所有bean都需要滿足自定義的Condition才能被自動(dòng)加載。
二、spring-boot提供的幾個(gè)autoconfigure annotation
springboot為我們提供了一批實(shí)用的XxxCondition,查看了他們的源碼后發(fā)現(xiàn),他們都實(shí)現(xiàn)了spring提供的Condition接口,然后編寫對(duì)應(yīng)的annotation。我們?cè)谑褂盟麄兊臅r(shí)候,只需要在需要的地方寫上這些annotation就好了。這些注解都在springboot提供的jar包中
package org.springframework.boot.autoconfigure.condition

通過這幾個(gè)annotation的命名,我們已經(jīng)能夠大概的猜測(cè)到他們能夠?qū)崿F(xiàn)哪些功能。以下舉出其中幾個(gè)比較常用的注解用法,讀者可以查看源碼,知曉具體的使用方式。
1)@ConditionalOnBean/@ConditionalOnMissingBean當(dāng)容器中存在/不存在某個(gè)bean時(shí),加上此注解的bean被自動(dòng)注入

@Bean
@ConditionalOnBean(name="com.springboot.condition.User")
public Runnable runnableBean2() {
return () ->{};
}
@Bean
@ConditionalOnBean(value=User.class)
public Runnable runnableBean2() {
return () ->{};
}
2)@ConditionalOnJava根據(jù)當(dāng)前使用的JDK版本,判斷是否自動(dòng)注入
//使用jdk8才注入此bean
@Bean
@ConditionalOnJava(ConditionalOnJava.JavaVersion.EIGHT)
public Runnable runnableBean2() {
return () ->{};
}
3)@ConditionalOnWebApplication/@ConditionalOnWebApplicationweb環(huán)境下加載/不加載此bean
@Bean
@ConditionalOnWebApplication
public Runnable runnableBean2() {
return () ->{};
}
好了,Spring-Boot autoconfigure之Condition就到這里,有興趣的讀者可以自己去試驗(yàn)一下。接下來會(huì)持續(xù)推出一系列Java干貨,敬請(qǐng)期待。如果有不正確或是不完整的地方,還望讀者不吝賜教,直接評(píng)論!