Java注解@Conditional与@Profile的使用区别

 更新时间:2025年05月10日 16:42:11   作者:Stay Passion  
这篇文章主要介绍了Java注解@Conditional与@Profile的使用区别,@Profile和@Conditional是Spring提供的两种常用机制,它们可以根据不同的条件动态决定某些Bean是否加载,从而实现环境隔离、模块选择、特性开关等功能,需要的朋友可以参考下

前言

在 Spring 应用开发中,条件化 Bean 注册是配置灵活性的关键一环。@Profile@Conditional 是 Spring 提供的两种常用机制,它们可以根据不同的条件动态决定某些 Bean 是否加载,从而实现环境隔离、模块选择、特性开关等功能。本文将系统讲解这两个注解的作用、使用方式及它们之间的区别与协同方式。

一、什么是@Profile

基本概念

@Profile 注解用于指定某个 Bean 或配置类仅在指定的 Profile 环境下生效。它常用于区分开发、测试和生产环境的配置。

@Configuration
@Profile("dev")
public class DevDataSourceConfig {
    @Bean
    public DataSource dataSource() {
        return new HikariDataSource("jdbc:mysql://localhost/dev_db");
    }
}

激活方式

  • application.yml: spring.profiles.active: dev
  • 启动参数:--spring.profiles.active=dev
  • SpringApplicationBuilder: .profiles("dev")

二、什么是@Conditional

基本概念

@Conditional 注解提供更通用的条件判断能力。它的参数是一个实现了 Condition 接口的类,Spring 会调用该类的 matches 方法决定是否加载对应的 Bean。

@Bean
@Conditional(WindowsCondition.class)
public ListService windowsListService() {
    return new WindowsListService();
}

自定义Condition 示例

public class WindowsCondition implements Condition {
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        return context.getEnvironment().getProperty("os.name").contains("Windows");
    }
}

三、两者的对比

维度@Profile@Conditional
粒度环境级别配置代码级别、属性级别、任意条件
简洁性简洁易用,约定大于配置灵活但需要手动实现 Condition 接口
适用场景多环境配置隔离(dev/test/prod)按任意运行时条件控制 Bean 加载,如系统变量、类存在性等
可组合性可配合 @Configuration@Component 使用可与任意 Spring 注解组合
底层原理本质是 @Conditional(ProfileCondition.class)完全自定义 Condition 实现类

四、实战示例

Profile+Conditional联合使用

@Configuration
@Profile("prod")
public class CacheConfig {
    @Bean
    @Conditional(RedisPresentCondition.class)
    public CacheManager redisCacheManager() {
        return new RedisCacheManager();
    }
}

此配置表示仅在 prod 环境下,且类路径中存在 RedisClient 类时,才创建 redisCacheManager Bean。

五、进阶@Conditional派生注解

Spring Boot 提供了多个 @Conditional 的派生注解,简化了常见场景的条件配置:

@ConditionalOnProperty

作用:根据配置文件中某个属性是否存在及其值决定是否加载 Bean

@Bean
@ConditionalOnProperty(name = "feature.user.enable", havingValue = "true", matchIfMissing = false)
public UserFeatureService featureService() {
    return new UserFeatureService();
}

@ConditionalOnMissingBean

作用:仅在指定 Bean 不存在时注册当前 Bean,用于提供默认实现。

@Bean
@ConditionalOnMissingBean(DataSource.class)
public DataSource defaultDataSource() {
    return new HikariDataSource();
}

@ConditionalOnBean

作用:当 Spring 上下文中存在某个 Bean 时,才注入当前 Bean。

@Bean
@ConditionalOnBean(RedisClient.class)
public CacheManager redisCacheManager() {
    return new RedisCacheManager();
}

@ConditionalOnClass

作用:当类路径下存在某个类时才加载 Bean,适合做组件自动装配。

@Bean
@ConditionalOnClass(name = "com.fasterxml.jackson.databind.ObjectMapper")
public JsonConverter jsonConverter() {
    return new JacksonJsonConverter();
}

这些注解极大简化了自动配置的条件逻辑,是 Spring Boot 自动装配机制的核心支撑。

六、总结

注解作用适合场景
@Profile按环境(如 dev/prod)激活 Bean多环境隔离配置
@Conditional根据任意条件(如操作系统、类路径)激活 Bean灵活控制、扩展性强的模块化配置

在实际项目中,两者可结合使用,构建高度灵活、可配置的应用架构,是 Spring 框架解耦和模块控制的重要工具。

建议在配置类中大量使用 @Profile 做环境隔离,在具体 Bean 中使用 @Conditional 做条件控制。

以上就是Java注解@Conditional与@Profile的使用区别的详细内容,更多关于Java注解@Conditional与@Profile的资料请关注脚本之家其它相关文章!

相关文章

  • 解析Java内存分配和回收策略以及MinorGC、MajorGC、FullGC

    解析Java内存分配和回收策略以及MinorGC、MajorGC、FullGC

    本节将会介绍一下:对象的内存分配与回收策略;对象何时进入新生代、老年代;MinorGC、MajorGC、FullGC的定义区别和触发条件;还有通过图示展示了GC的过程。
    2021-09-09
  • 一文带你掌握Java Future模式的灵活应用

    一文带你掌握Java Future模式的灵活应用

    Future模式,简单来说,就是一种能够管理异步操作的方式,它可以让咱们的程序在执行一个耗时任务的同时,还能继续做其他事情,下面我们就来看看Future模式的具体应用吧
    2024-01-01
  • SpringBoot应用部署于外置Tomcat容器的方法

    SpringBoot应用部署于外置Tomcat容器的方法

    这篇文章主要介绍了SpringBoot应用部署于外置Tomcat容器的方法,本文分步骤给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2018-06-06
  • Java如何使用Optional与Stream取代if判空逻辑(JDK8以上)

    Java如何使用Optional与Stream取代if判空逻辑(JDK8以上)

    这篇文章主要给大家介绍了关于Java如何使用Optional与Stream取代if判空逻辑(JDK8以上)的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用Java具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-09-09
  • JAVA面试题String产生了几个对象

    JAVA面试题String产生了几个对象

    这篇文章主要介绍了JAVA面试题 String s = new String("xyz");产生了几个对象?,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-07-07
  • 浅谈springcloud常用依赖和配置

    浅谈springcloud常用依赖和配置

    鉴于很多小伙伴常问spring cloud常用依赖和配置,今天特地整理了本篇文章,文中有非常详细的代码示例,对正在学习的小伙伴们很有帮助,需要的朋友可以参考下
    2021-05-05
  • java多线程:基础详解

    java多线程:基础详解

    这篇文章主要介绍了java多线程编程实例,分享了几则多线程的实例代码,具有一定参考价值,加深多线程编程的理解还是很有帮助的,需要的朋友可以参考下。
    2021-08-08
  • RestFul风格 — 使用@PathVariable传递参数报错404的解决

    RestFul风格 — 使用@PathVariable传递参数报错404的解决

    这篇文章主要介绍了RestFul风格 — 使用@PathVariable传递参数报错404的解决,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-10-10
  • Java实现链表数据结构的方法

    Java实现链表数据结构的方法

    这篇文章主要介绍了Java实现链表数据结构的相关资料,每一个链表都包含多个节点,节点又包含两个部分,一个是数据域(储存节点含有的信息),一个是引用域(储存下一个节点或者上一个节点的地址),需要的朋友可以参考下
    2022-01-01
  • 一文了解MyBatis Plus批量数据插入功能

    一文了解MyBatis Plus批量数据插入功能

    mybatisPlus底层的新增方法是一条一条的新增的,下面这篇文章主要给大家介绍了MyBatis Plus批量数据插入功能的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下
    2021-09-09

最新评论