浅谈 Spring Boot 中的 @Conditional 注解

简介: Spring boot 中的 @Conditional 注解是一个不太常用到的注解,但确实非常的有用,我们知道 Spring Boot 是根据配置文件中的内容,决定是否创建 bean,以及如何创建 bean 到 Spring 容器中,而 Spring boot 自动化配置的核心控制,就是 @Conditional 注解。@Conditional 注解是 Spring 4.0 之后出的一个注解,与其搭配的一个接口是 Condition,@Conditional 注解会根据具体的条件决定是否创建 bean 到容器中,接下来看看 @Conditional 注解的简单使用。

概述


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 中加上一个自定义配置:

_4(2WATAV0)}I$QZ[09EP}Q.png

这里我们决定,这个配置中包含了 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 已经创建了:

X5KKU2PWVATSDGERIB2UE$C.png

如果把 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 中添加一个自定义配置:

D5G5$F`B1[[]QSN59@K89_E.png

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 不会被创建,你可以自己试一下。根据这个特性,我们可以给一些特定的配置加上一个开关,非常方便控制。

这里我只是列举了几个常用的注解,你可以查看官方文档,里面有更详细的说明:

参考文档:Spring Boot 官网文档

相关文章
|
7天前
|
XML Java 数据格式
SpringBoot入门(8) - 开发中还有哪些常用注解
SpringBoot入门(8) - 开发中还有哪些常用注解
24 0
|
14天前
|
XML JSON Java
SpringBoot必须掌握的常用注解!
SpringBoot必须掌握的常用注解!
40 4
SpringBoot必须掌握的常用注解!
|
4天前
|
存储 运维 安全
Spring运维之boot项目多环境(yaml 多文件 proerties)及分组管理与开发控制
通过以上措施,可以保证Spring Boot项目的配置管理在专业水准上,并且易于维护和管理,符合搜索引擎收录标准。
14 2
|
15天前
|
存储 缓存 Java
Spring缓存注解【@Cacheable、@CachePut、@CacheEvict、@Caching、@CacheConfig】使用及注意事项
Spring缓存注解【@Cacheable、@CachePut、@CacheEvict、@Caching、@CacheConfig】使用及注意事项
56 2
|
15天前
|
JSON Java 数据库
SpringBoot项目使用AOP及自定义注解保存操作日志
SpringBoot项目使用AOP及自定义注解保存操作日志
32 1
|
10天前
|
存储 安全 Java
springboot当中ConfigurationProperties注解作用跟数据库存入有啥区别
`@ConfigurationProperties`注解和数据库存储配置信息各有优劣,适用于不同的应用场景。`@ConfigurationProperties`提供了类型安全和模块化的配置管理方式,适合静态和简单配置。而数据库存储配置信息提供了动态更新和集中管理的能力,适合需要频繁变化和集中管理的配置需求。在实际项目中,可以根据具体需求选择合适的配置管理方式,或者结合使用这两种方式,实现灵活高效的配置管理。
10 0
|
22天前
|
存储 Java 数据管理
强大!用 @Audited 注解增强 Spring Boot 应用,打造健壮的数据审计功能
本文深入介绍了如何在Spring Boot应用中使用`@Audited`注解和`spring-data-envers`实现数据审计功能,涵盖从添加依赖、配置实体类到查询审计数据的具体步骤,助力开发人员构建更加透明、合规的应用系统。
|
6月前
|
XML 安全 Java
深入实践springboot实战 蓄势待发 我不是雷锋 我是知识搬运工
springboot,说白了就是一个集合了功能的大类库,包括springMVC,spring,spring data,spring security等等,并且提供了很多和可以和其他常用框架,插件完美整合的接口(只能说是一些常用框架,基本在github上能排上名次的都有完美整合,但如果是自己写的一个框架就无法实现快速整合)。
|
3月前
|
缓存 Java Maven
Java本地高性能缓存实践问题之SpringBoot中引入Caffeine作为缓存库的问题如何解决
Java本地高性能缓存实践问题之SpringBoot中引入Caffeine作为缓存库的问题如何解决
|
6月前
|
Java 数据安全/隐私保护
Neo4j【付诸实践 01】SpringBoot集成报错org.neo4j.driver.exceptions.ClientException:服务器不支持此驱动程序支持的任何协议版本(解决+源代码)
Neo4j【付诸实践 01】SpringBoot集成报错org.neo4j.driver.exceptions.ClientException:服务器不支持此驱动程序支持的任何协议版本(解决+源代码)
316 1