简述Spring中的Conditional条件的使用

208 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 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对象;