开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第31天,点击查看活动详情
前言
今天我们来说另一种动态创建Bean的功能,就是Conditional条件创建Bean对象;我们在使用一些第三方框架的时候,经常看到@Bean上面有一个@ConditionalOnBean注解或者@ConditionOnMissingBean注解,这些以Conditional开头的注解其实都是条件语句,标识当前Bean只有在满足Conditional条件的情况下才会被创建;
示例
@ConditionalOnBean
咱们先来用用@ConditionalOnBean注解:
@Configuration
public class ConditionTestConfig{
@Bean("classA")
public ClassA classA(){
return new ClassA();
}
@ConditionalOnBean(value = {ClassA.class})
@Bean("classB")
public ClassB classB(){
return new ClassB();
}
}
上面示例的意思就是:只有当ClassA这个Bean存在的情况下才能创造ClassB这个Bean;
@ConditionalOnClass
这个注解其实和上面的@ConditionalOnBean注解类似,而且@ConditionalOnBean更加强大,所以一般情况下还是建议使用@ConditionalOnBean;
@ConditionalOnJava
这个就显而易见了,它可以指定Bean在哪些java版本下才会被创建:
@Configuration
// java 17及以上版本才会生效
@ConditionalOnJava(JavaVersion.SEVENTEEN)
public class ConditionTestConfig{
@Bean("classA")
public ClassA classA(){
return new ClassA();
}
}
上述代码指定了只有在java17及以上版本的才会创建ClassA这个Bean;
@ConditionalOnMissingBean
与@ConditionalOnBean不同的是,@ConditionalOnMissingBean是在目标Bean不存在的情况下才会创建当前Bean:
@Configuration
public class ConditionTestConfig{
@Bean("classA")
public ClassA classA(){
return new ClassA();
}
// 这个情况下是不会创建ClassB的,因为ClassA当前是存在的
@ConditionalOnMissingBean(value = {ClassA.class})
@Bean("classB")
public ClassB classB(){
return new ClassB();
}
}
@ConditionalOnMissingClass
与@ConditionalOnMissingBean类似,@ConditionalOnMissingBean功能足够包含@ConditionalOnMissingClass,所以还是建议使用@ConditionalOnMissingBean;
@ConditionalOnNotWebApplication
这个是在非web环境下才会生效的条件:
@Configuration
// 只有的非web环境下才会创建ClassA
@ConditionalOnNotWebApplication
public class ConditionTestConfig{
@Bean("classA")
public ClassA classA(){
return new ClassA();
}
}
@ConditionalOnWebApplication
与上面的示例相反,@ConditionalOnWebApplication只有在web环境下才会生效,默认是在任何web环境下都会生效,我们自己也可以指定SERVLET还是REACTIVE;
@ConditionalOnProperty
这个注解可以根据配置文件的内容来动态创建Bean:
@Configuration
public class ConditionTestConfig{
@ConditionalOnProperty(prefix = "spring.http.encoding", value = "enabled", matchIfMissing = true)
@Bean("classA")
public ClassA classA(){
return new ClassA();
}
}
当配置文件中配置了spring.http.encoding.enabled这个属性的时候,才会创建ClassA这个Bean;如果我们配置了matchIfMissing = true,那么即使配置文件中没有找到spring.http.encoding.enabled这个配置,那么依然会创建ClassA这个Bean;
@ConditionalOnResource
这个注解可以判断classpath是否存在目标文件,只有在目标文件存在的情况下才会创建Bean:
@Configuration
public class ConditionTestConfig{
@ConditionalOnResource(resources={"classpath:website.properties"})
@Bean("classA")
public ClassA classA(){
return new ClassA();
}
}
上述示例的意思是在classpath下存在website.properties的情况下,才会创建ClassA这个Bean对象;