Spring(非Spring Boot)如何基于application.properties用@Profile加载环境配置
纯Spring(非Spring Boot)完全可以基于@Profile实现按环境动态加载配置属性的能力
你在网上搜到的硬编码独立Bean的示例,只是@Profile最基础的入门演示,绝非配置属性加载的标准实现方式。下面针对你的两个疑问做明确解答,同时给出Spring 5环境下可直接运行的参考实现。
核心疑问解答
疑问1:每个环境硬编码独立Bean的写法是配置加载的标准实现吗?
- 完全不是。这种写法只是为了演示
@Profile的核心作用:当指定环境激活时,对应标注的Bean才会被注册到Spring容器。 - 这种写法没有任何配置文件加载的逻辑,所有环境差异值都硬编码在Java代码里,完全违背了配置和代码分离的设计原则,实际项目中根本不会这么用。
疑问2:必须为每个Profile单独编写专属Bean吗?
- 完全不需要。
@Profile的设计定位是控制配置类/Bean的生效范围,不是要求你把所有环境差异值都硬编码成独立Bean。你可以通过@Profile关联不同的外部配置文件加载逻辑,实现一套通用的Bean定义,动态注入对应环境的属性值。
Spring 5 纯环境下的标准实现方案
整体实现逻辑和Spring Boot的底层Profile机制完全一致,只是需要手动完成配置加载的步骤,不需要依赖Spring Boot的自动配置能力。
实现流程
- 按环境拆分独立的properties配置文件,只存键值对形式的配置属性,不硬编码Bean逻辑
- 编写轻量的带
@Profile的配置类,每个类仅负责加载对应环境的properties文件到Spring容器的Environment中 - 编写通用的业务Bean定义,直接通过Spring的属性绑定能力,读取当前激活环境对应的属性值完成初始化,所有环境共用同一套Bean逻辑
可运行代码示例
第一步:准备环境配置文件
在项目resources目录下,按环境创建独立的配置文件:
application-dev.properties(开发环境配置)
db.url=jdbc:mysql://localhost:3306/dev_db db.driver=com.mysql.cj.jdbc.Driver db.username=dev_user db.password=dev_pwd123
application-prod.properties(生产环境配置)
db.url=jdbc:mysql://10.0.1.20:3306/prod_db db.driver=com.mysql.cj.jdbc.Driver db.username=prod_user db.password=prod_pwd456
第二步:编写带@Profile的配置加载类
每个配置类的作用仅为加载对应环境的配置文件,不需要写任何业务Bean:
// 开发环境配置加载类:仅当dev环境激活时生效 @Configuration @Profile("dev") @PropertySource("classpath:application-dev.properties") public class DevEnvironmentConfig { // 无任何@Bean方法,@PropertySource注解会自动将当前配置文件的属性加载到Spring Environment中 } // 生产环境配置加载类:仅当prod环境激活时生效 @Configuration @Profile("prod") @PropertySource("classpath:application-prod.properties") public class ProdEnvironmentConfig { // 无任何业务逻辑代码 }
第三步:编写通用的属性绑定和业务Bean
所有环境共用同一套Bean定义,自动适配当前激活环境的配置值:
// 通用数据库属性绑定类:Spring 5.1及以上版本原生支持@ConfigurationProperties注解 @Configuration @ConfigurationProperties(prefix = "db") public class DBProperties { // 这些属性会自动从当前激活环境加载的配置文件中取值 private String url; private String driver; private String username; private String password; // 必须添加getter/setter方法,否则属性绑定无法生效 public String getUrl() {return url;} public void setUrl(String url) {this.url = url;} public String getDriver() {return driver;} public void setDriver(String driver) {this.driver = driver;} public String getUsername() {return username;} public void setUsername(String username) {this.username = username;} public String getPassword() {return password;} public void setPassword(String password) {this.password = password;} } // 通用数据源配置:所有环境共用同一份逻辑 @Configuration public class DataSourceConfiguration { @Autowired private DBProperties dbProperties; @Bean public DataSource dataSource() { // 不管当前激活的是dev还是prod环境,dbProperties里的值都是对应环境的配置 DriverManagerDataSource dataSource = new DriverManagerDataSource(); dataSource.setUrl(dbProperties.getUrl()); dataSource.setDriverClassName(dbProperties.getDriver()); dataSource.setUsername(dbProperties.getUsername()); dataSource.setPassword(dbProperties.getPassword()); return dataSource; } }
激活对应环境的Profile方式
纯Spring环境下激活Profile没有Spring Boot的自动配置便利,常见的三种实现方式:
- 编程式激活:在初始化Spring容器时,手动设置激活的Profile
public class ApplicationMain { public static void main(String[] args) { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); // 这里指定激活dev环境,替换为prod即可加载生产配置 context.getEnvironment().setActiveProfiles("dev"); // 注册所有配置类 context.register( DevEnvironmentConfig.class, ProdEnvironmentConfig.class, DataSourceConfiguration.class, DBProperties.class ); context.refresh(); // 验证配置加载结果 DataSource dataSource = context.getBean(DataSource.class); System.out.println("当前加载的数据库连接地址:" + dataSource.getUrl()); } }
- JVM参数激活:启动时添加JVM参数
-Dspring.profiles.active=dev,Spring容器初始化时会自动读取该系统属性作为激活的Profile - Web环境激活:传统Spring MVC项目可以在web.xml中配置
context-param,指定参数名spring.profiles.active的值,完成环境激活
和硬编码示例的核心差异
- 不需要为每个环境重复编写Bean定义,所有环境共用同一套业务逻辑,仅属性值从对应配置文件读取
- 调整配置值时只需要修改properties文件,不需要改动Java代码重新编译
- 新增环境时,仅需要新增一个对应环境的properties文件、一个带@Profile的配置加载类,不需要改动原有业务代码
内容的提问来源于stack exchange,提问作者ever alian
相关产品推荐
相关产品推荐

