本文主要介绍spring和springboot提供的几个annotation和interface实现符合几种既定条件或自定义条件下的autoconfigure
一、spring实现自定义条件下的autoconfigure
spring为我们提供了@Conditional
和Condition.class
搭配使用的方式实现自定义条件下的autoconfigure,源码如下:
编写一个class,继承Condition
这个接口,重写matches()
方法,当该方法返回true时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
两个参数,我们可以通过ConditionContext
获取到编写在application-xxx.properties中的配置信息。
application.properties配置文件内容如下:注意我们现在定义的value和Mycondition
中定义的不同
what.is.you.name=heiheihei
编写一个Config类,其中runnableBean1、runnableBean3需要满足我们以上自定义的条件才允许被自动注入。
@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 () ->{};
}
}
执行main方法结果如下:
@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
中定义的值后执行结果如下:
我们发现,自定义的MyCondition已经生效。细心的读者可能发现,@Conditional注解源码中传入的value是一个数组
Class<? extends Condition>[] value();
,所以我们可以传入多个自定义Condition,例如@Condition({MyCondition.class, YourCondition.class})
另外,@Conditianal
不仅可以写在方法上,还可以写在configuration.class上,这样该类中的所有bean都需要满足自定义的Condition才能被自动加载。
二、spring-boot提供的几个autoconfigure annotation
springboot为我们提供了一批实用的XxxCondition,查看了他们的源码后发现,他们都实现了spring提供的Condition接口,然后编写对应的annotation。我们在使用他们的时候,只需要在需要的地方写上这些annotation就好了。这些注解都在springboot提供的jar包中
package org.springframework.boot.autoconfigure.condition
通过这几个annotation的命名,我们已经能够大概的猜测到他们能够实现哪些功能。以下举出其中几个比较常用的注解用法,读者可以查看源码,知晓具体的使用方式。
1)@ConditionalOnBean
/@ConditionalOnMissingBean
当容器中存在/不存在某个bean时,加上此注解的bean被自动注入
@Bean
@ConditionalOnBean(name="com.springboot.condition.User")
public Runnable runnableBean2() {
return () ->{};
}
@Bean
@ConditionalOnBean(value=User.class)
public Runnable runnableBean2() {
return () ->{};
}
2)@ConditionalOnJava
根据当前使用的JDK版本,判断是否自动注入
//使用jdk8才注入此bean
@Bean
@ConditionalOnJava(ConditionalOnJava.JavaVersion.EIGHT)
public Runnable runnableBean2() {
return () ->{};
}
3)@ConditionalOnWebApplication
/@ConditionalOnWebApplication
web环境下加载/不加载此bean
@Bean
@ConditionalOnWebApplication
public Runnable runnableBean2() {
return () ->{};
}
好了,Spring-Boot autoconfigure之Condition就到这里,有兴趣的读者可以自己去试验一下。接下来会持续推出一系列Java干货,敬请期待。如果有不正确或是不完整的地方,还望读者不吝赐教,直接评论!