SpringBoot中的@Conditional 注解的使用
作者:roseduan
概述
Spring boot 中的 @Conditional 注解是一个不太常用到的注解,但确实非常的有用,我们知道 Spring Boot 是根据配置文件中的内容,决定是否创建 bean,以及如何创建 bean 到 Spring 容器中,而 Spring boot 自动化配置的核心控制,就是 @Conditional 注解。
@Conditional 注解是 Spring 4.0 之后出的一个注解,与其搭配的一个接口是 Condition,@Conditional 注解会根据具体的条件决定是否创建 bean 到容器中,接下来看看 @Conditional 注解的简单使用。
1. @Conditional 和 Condition 接口搭配使用
这里需要实现的功能是,我们根据配置文件中的具体内容,来决定是否创建 bean,首先我们在 application.yml 中加上一个自定义配置:
这里我们决定,这个配置中包含了 product 这个字符串的时候,才创建 bean。Product 是我自己随便创建的一个实体类,你可以自行创建。
新建一个类 ProductCondition
,内容如下:
public class ProductCondition implements Condition { @Override public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) { //从配置文件中获取属性 String property = conditionContext.getEnvironment().getProperty("create.bean"); if (property != null){ return property.contains("product"); } else { return false; } } }
这个类实现了 Condition 接口,这个接口只有一个方法,我们从配置文件中获取刚才创建的自定义配置,如果配置中包含了 product 这个字符串,就会返回 true。
接下来创建一个配置类 ProductConfig,内容如下:
@Configuration public class ProductConfig { @Conditional(ProductCondition.class) @Bean(name = "product") public Product createProd(){ return Product.builder().id(12312).categoryId(12). productName("Mac Book Pro").productImg("prod.png") .productPrice(18000).build(); } }
我们在创建的 bean 方法前面加上了 @Conditional 注解,判断的标准是刚才的 ProductCondition,如果是 true,则创建 bean,否则不创建。我们写一个测试类,来测试一下 bean 是否被创建了。测试代码如下:
@Slf4j @SpringBootTest @RunWith(SpringRunner.class) public class ProductConfigTest { @Test public void createProd() { try { Product product = SpringContextUtil.getBean("product", Product.class); if (product != null){ System.out.println("创建了 bean : " + product.toString()); } } catch (Exception e){ log.info("发生异常,{}", e.getMessage()); System.out.println("没有创建 bean"); } } }
运行测试代码,发现 bean 已经创建了:
如果把 application.yml 中的配置改一下,不包含 product 这个字符串,那么返回的是 false,bean 则不会被创建,你可以试一下。
2. @ConditionalOnClass 的使用
这个注解的属性可以跟上一个类的完整路径或者是类的 Class 对象,如果类存在,则会创建 bean,例如下面的例子:
@Configuration public class ProductConfig { @ConditionalOnClass(name = "com.roseduan.demo.entity.Product") @Bean(name = "product") public Product createProd(){ return Product.builder().id(12312).categoryId(12). productName("Mac Book Pro").productImg("prod.png") .productPrice(18000).build(); } }
这个路径下面的实体类 Product 是存在的,所以会创建 bean,如果是一个不存在的类,则不会创建。
3. @ConditionalOnProperty 的使用
这个注解可以直接从配置文件中获取属性,然后做为是否创建 bean 的依据。例如我们在 application.yml 中添加一个自定义配置:
ProductConfig 类的内容是这样的:
@Configuration public class ProductConfig { @ConditionalOnProperty(value = "create.product.bean") @Bean(name = "product") public Product createProd(){ return Product.builder().id(12312).categoryId(12). productName("Mac Book Pro").productImg("prod.png") .productPrice(18000).build(); } }
这里使用了 @ConditionalOnProperty 注解,从文件中读取配置,因为我们设置的是 true,所以这个 bean 会被创建,如果设置成 false,则 bean 不会被创建,你可以自己试一下。根据这个特性,我们可以给一些特定的配置加上一个开关,非常方便控制。
4.@Conditional 的实现子注解
springboot 提供了大量的 @Conditional 子注解供我们使用,我们只需知道有哪些常用的子注解供我们使用即可。
springboot 提供的 @Conditional 子注解有:
@ConditionalOnBean @ConditionalOnClass @ConditionalOnCloudPlatform @ConditionalOnExpression @ConditionalOnJava @ConditionalOnJndi @ConditionalOnMissingBean @ConditionalOnMissingClass @ConditionalOnNotWebApplication @ConditionalOnProperty @ConditionalOnResource @ConditionalOnSingleCandidate @ConditionalOnWarDeployment @ConditionalOnWebApplication 这些子注解是如何实现的呢?我们以 @ConditionalOnBean 注解为例看下源码: @Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented @Conditional({OnBeanCondition.class}) public @interface ConditionalOnBean { Class<?>[] value() default {}; String[] type() default {}; Class<? extends Annotation>[] annotation() default {}; String[] name() default {}; SearchStrategy search() default SearchStrategy.ALL; Class<?>[] parameterizedContainer() default {}; }
可以看到 OnBeanCondition 是 Condition 接口的具体实现类。
我们挑选一些日常常用的子注解做具体的说明。
这里我只是列举了几个常用的注解,你可以查看官方文档,里面有更详细的说明:
参考文档:官网文档
到此这篇关于SpringBoot中的@Conditional 注解的使用的文章就介绍到这了,更多相关SpringBoot @Conditional注解内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!