原文网址:Spring--条件注入(条件装配)--详解_IT利刃出鞘的博客-CSDN博客
简介
说明
本文介绍SpringBoot如何将某个类根据条件注入容器。比如:如果某个类不存在,则将类注入;如果某个配置没开启,则不注入。
相关网址
Spring--条件注入(条件装配)--实例_IT利刃出鞘的博客-CSDN博客
源码中的使用
在Spring Boot的源码中,比如涉及到Http编码的自动配置、数据源类型的自动配置等大量的使用到了@ConditionalOnProperty注解。
HttpEncodingAutoConfiguration类中部分源代码:
@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties(HttpProperties.class)
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
@ConditionalOnClass(CharacterEncodingFilter.class)
@ConditionalOnProperty(prefix = "spring.http.encoding", value = "enabled", matchIfMissing = true)
public class HttpEncodingAutoConfiguration {
// 省略内部代码
}
DataSourceConfiguration类中部分代码:
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(org.apache.tomcat.jdbc.pool.DataSource.class)
@ConditionalOnMissingBean(DataSource.class)
@ConditionalOnProperty(name = "spring.datasource.type", havingValue = "org.apache.tomcat.jdbc.pool.DataSource",
matchIfMissing = true)
static class Tomcat {
// 省略内部代码
}
已有的条件注解
注解大全
注解 | 说明 | 示例 |
@ConditionalOnProperty | 要求配置属性匹配条件 | @ConditionalOnProperty( prefix = "spring.http.encoding", value = "enabled", matchIfMissing = true) |
@ConditionalOnBean | 容器中存在对应实例时,返回true。 当给定的类型、类名、注解、昵称在beanFactory中存在时返回true。 若不指定name,则为本bean的名字。 | @ConditionalOnBean(Abc.class) 或 @ConditionalOnBean(name="abc") |
@ConditionalOnMissingBean | 容器中不存在对应实例时,返回true。 当给定的类型、类名、注解、昵称在beanFactory中不存在时返回true。各类型间是or的关系。 若不指定name,则为本bean的名字。 | |
@ConditionalOnClass | 当给定的类在类路径上存在时返回true,各类型间是and的关系 | @ConditionalOnClass(Abc.class) |
@ConditionalOnMissingClass | 当给定的类在类路径上不存在时返回true,各类型间是and的关系 | |
@ConditionalOnSingleCandidate | 当给定类型的bean存在并且指定为Primary的给定类型存在时,返回true | |
@ConditionalOnCloudPlatform | 当所配置的CloudPlatform为激活时返回true | |
@ConditionalOnExpression | spel表达式执行为true | 详见下方。 |
@ConditionalOnJava | 运行时的java版本号是否包含给定的版本号.如果包含,返回匹配,否则,返回不匹配 | |
@ConditionalOnJndi | 给定的jndi的Location 必须存在一个.否则,返回不匹配 | |
@ConditionalOnNotWebApplication | web环境不存在时 | |
@ConditionalOnWebApplication | web环境存在时 | |
@ConditionalOnResource | 要求制定的资源存在 |
详解
@ConditionalOnProperty
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
@Documented
@Conditional({OnPropertyCondition.class})
public @interface ConditionalOnProperty {
String[] value() default {}; //数组,获取对应property名称的值,与name不可同时使用
String prefix() default ""; //property名称的前缀,可有可无
String[] name() default {}; //数组,property完整名称或部分名称(可与prefix组合使用,组成完整的property名称),与value不可同时使用
String havingValue() default ""; //可与name组合使用,比较获取到的属性值与havingValue给定的值是否相同,相同才加载配置
boolean matchIfMissing() default false; //缺少该property时是否可以加载。如果为true,没有该property也会正常加载;反之报错
}
单个值(key必须存在,且value必须是指定值)
@ConditionalOnProperty("config1.enable", havingValue="true")
单个值(key必须存在,不关心value)
@ConditionalOnProperty("config1.enable")
单个值(key不存在时可以匹配;key存在,value为指定值也匹配)
@ConditionalOnProperty(name = {"config1.enable"}, havingValue="true", matchIfMissing=true)
多个值(多个key必须存在,且value必须都是指定值)
@ConditionalOnProperty(name={"config1.enable","config.all"}, havingValue="true")
多个值(多个key必须存在,不关心value)
@ConditionalOnProperty(name={"config1.enable","config.all"})
注意事项
name这个字段,必须与yml的配置一模一样(不支持宽松匹配)。比如:
application.yml
custom.nick-name: Tony
Java实体类字段
private String nickName;
条件注解
@ConditionalOnProperty(name={"custom.nick-name"}, havingValue="true")
@ConditionalOnClass
上边是文章的部分内容,为便于维护,全文已转移到此网址:Spring-条件注入(条件装配)-详解 - 自学精灵