Spring入门实战之Profile详解
发布时间 - 2026-01-10 22:59:45 点击率:次前言

Spring中的Profile功能其实早在Spring 3.1的版本就已经出来,它可以理解为我们在Spring容器中所定义的Bean的逻辑组名称,只有当这些Profile被激活的时候,才会将Profile中所对应的Bean注册到Spring容器中。
看到Profile这个关键字,或许你从来没有正眼瞧过他,又或者脑海中有些模糊的印象,比如除了这里Springmvc中的Profile,maven中也有Profile的标签。
从字面意思来看,Profile表示侧面,那什么情况下才会用到侧面这个功能呢,而侧面具体又有什么含义呢
打一个比方,对于数据库的配置问题,在开发的眼中可以使用嵌入的数据库,并且加载测试数据(后面会给出代码示例)。但是在测试的眼中,可能会配一个数据库连接池类似这样
@Bean(destroyMethod="close")
public DataSource dataSource () {
BasicDataSource dataSource = new BasicDataSource();
dataSource.setUrl("jdbc:h2:tcp://dbserver/~/test");
dataSource.setDriverClassName("org.h2.Driver");
dataSource.setUsername("sa");
dataSource.setPassword("password");
dataSource.setInitialSize(20);
dataSource.setMaxActive(30);
return dataSource;
}
当然还有产品环境下的配置等等。对于这种百花齐放的配置方式你还能说什么,默默的为这一套套的环境都部署相应的配置文件啊,没有profile这套我们一直都是这么做。
但是现在有了Profile,我们就多了一种选择,一种更加智能省心的配置方式。通过Profile配置,Spring可以在根据环境在运行阶段来决定bean的创建与否,先举例如下,主要从Profile bean的配置和激活来展开。
Profile bean的配置
通过注解@Profile配置
对于上面比方中的第一种情况,在开发环境中我们配置一个数据源可能是这样的
@Bean(destroyMethod = "shutdown")
public DataSource embeddedDataSource() {
return new EmbeddedDatabaseBuilder()
.addScript("classpath:schema.sql")
.addScript("classpath:test-data.sql")
.build();
}
这里会使用EmbeddedDatabaseBuilder创建一个嵌入式数据库,模式定义在类文件下的schema.sql文件中
schema.sql
create table Things ( id identity, name varchar(100) );
这里定义了一张Things表包含了两个字段
除了模式文件,还需要通过test-data.sql加载测试数据
test-data.sql
insert into Things (name) values ('A')
对于这个@Bean完全不知道是放在开发的环境下创建还是产品的环境下。所以我们这里可以使用注解@Profile帮助我们为这个bean打上标识。
从Spring 3.1版本中就引入了bean profile的功能,可以让你将不同的bean定义到一个或者多个profile里,然后在部署应用时告知要激活那个profile,则相应的bean就会被创建。
比如这里
@Configuration
@Profile("dev")
public class DevelopmentProfileConfig {
@Bean(destroyMethod = "shutdown")
public DataSource embeddedDataSource() {
return new EmbeddedDatabaseBuilder()
.setType(EmbeddedDatabaseType.H2)
.addScript("classpath:schema.sql")
.addScript("classpath:test-data.sql")
.build();
}
}
通过@Profile("dev")为EmbedderDataSource bean标记为dev环境下要创建的bean。
注意:1. @Profile被加载类级别上,如果dev profile没有被激活,那么类中对应的所有bean就不会被创建
2. 如果当前是dev环境被激活了,那么对于没有使用@Profile的bean都会被创建,被标记为其他的profile如prod,则不会创建相应的bean
3. 从3.2开始@Profile不仅仅可以加载类级别上,还可以加载方法上,具体代码如下
package com.myapp;
import javax.sql.DataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
import org.springframework.jndi.JndiObjectFactoryBean;
@Configuration
public class DataSourceConfig {
@Bean(destroyMethod = "shutdown")
@Profile("dev")
public DataSource embeddedDataSource() {
return new EmbeddedDatabaseBuilder()
.setType(EmbeddedDatabaseType.H2)
.addScript("classpath:schema.sql")
.addScript("classpath:test-data.sql")
.build();
}
@Bean
@Profile("prod")
public DataSource jndiDataSource() {
JndiObjectFactoryBean jndiObjectFactoryBean = new JndiObjectFactoryBean();
jndiObjectFactoryBean.setJndiName("jdbc/myDS");
jndiObjectFactoryBean.setResourceRef(true);
jndiObjectFactoryBean.setProxyInterface(javax.sql.DataSource.class);
return (DataSource) jndiObjectFactoryBean.getObject();
}
}
通过xml配置文件配置
除了简单的注解方式,我们哈可以通过在xml配置文件中声明的方式,具体配置如下
datasource-config.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:jee="http://www.springframework.org/schema/jee" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation=" http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <beans profile="dev"> <jdbc:embedded-database type="H2"> <jdbc:script location="classpath:schema.sql" /> <jdbc:script location="classpath:test-data.sql" /> </jdbc:embedded-database> </beans> <beans profile="prod"> <jee:jndi-lookup lazy-init="true" jndi-name="jdbc/myDatabase" resource-ref="true" proxy-interface="javax.sql.DataSource" /> </beans> </beans>
这里分别声明了两种环境以及对应的profile。
profile激活
虽然我们已经配置好了profile,但是如何激活相应的环境呢。这里我们需要两个属性spring.profile.active以及spring.profile.default。
如果spring.profile.active被赋值了,则spring.profile.default就不会起作用,如果spring.profie.active没有赋值,则使用默认的spring.profile.default设置的值。当然,如果两者都没有设置的话,则只会创建那些定义在相应的profile中的bean。
设置这两个属性的方式有很多:
作为DispactcherServlet的初始化参数
作为Web应用上下文参数
作为JNDI条目
作为环境变量
作为JVM的系统属性
在集成测试类上,使用@ActiveProfiles注解设置
比如我们在web.xml中可以声明代码如下
<?xml version="1.0" encoding="UTF-8"?> <web -app version="2.5" ...> //为上下文设置默认的profile <context-param> <param-name>spring.profile.default</param-name> <param-value>dev</param-value> </context-param> ... <servlet> ... //为Serlvet设置默认的profile <init-param> <param-name>spring-profiles.default</param-name> <param-value>dev</param-value> </init-prama> ... <web-app>
这样就可以指定需要启动那种环境,并准备相应的bean。
另外对于测试,spring为什么提供了一个简单的注解可以使用@ActiveProfiles,它可以指定运行测试的时候应该要激活那个profile。比如这里的测试类DevDataSourceTest
package profiles;
import static org.junit.Assert.*;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import javax.sql.DataSource;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.myapp.DataSourceConfig;
public class DataSourceConfigTest {
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes=DataSourceConfig.class)
@ActiveProfiles("dev")
public static class DevDataSourceTest {
@Autowired
private DataSource dataSource;
@Test
public void shouldBeEmbeddedDatasource() {
assertNotNull(dataSource);
JdbcTemplate jdbc = new JdbcTemplate(dataSource);
List<String> results = jdbc.query("select id, name from Things", new RowMapper<String>() {
@Override
public String mapRow(ResultSet rs, int rowNum) throws SQLException {
return rs.getLong("id") + ":" + rs.getString("name");
}
});
assertEquals(1, results.size());
assertEquals("1:A", results.get(0));
}
}
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes=DataSourceConfig.class)
@ActiveProfiles("prod")
public static class ProductionDataSourceTest {
@Autowired
private DataSource dataSource;
@Test
public void shouldBeEmbeddedDatasource() {
// should be null, because there isn't a datasource configured in JNDI
assertNull(dataSource);
}
}
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:datasource-config.xml")
@ActiveProfiles("dev")
public static class DevDataSourceTest_XMLConfig {
@Autowired
private DataSource dataSource;
@Test
public void shouldBeEmbeddedDatasource() {
assertNotNull(dataSource);
JdbcTemplate jdbc = new JdbcTemplate(dataSource);
List<String> results = jdbc.query("select id, name from Things", new RowMapper<String>() {
@Override
public String mapRow(ResultSet rs, int rowNum) throws SQLException {
return rs.getLong("id") + ":" + rs.getString("name");
}
});
assertEquals(1, results.size());
assertEquals("1:A", results.get(0));
}
}
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:datasource-config.xml")
@ActiveProfiles("prod")
public static class ProductionDataSourceTest_XMLConfig {
@Autowired(required=false)
private DataSource dataSource;
@Test
public void shouldBeEmbeddedDatasource() {
// should be null, because there isn't a datasource configured in JNDI
assertNull(dataSource);
}
}
}
运行shouldBeEmbeddedDatasource方法,测试通过
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流。
# spring
# profile
# 配置
# 注解
# 使用Spring boot 的profile功能实现多环境配置自动切换
# 浅谈关于spring profile的误解
# Spring Boot使用profile如何配置不同环境的配置文件
# spring @profile注解的使用方法
# Maven管理SpringBoot Profile详解
# 详解Spring Boot Profiles 配置和使用
# 详解springboot + profile(不同环境读取不同配置)
# 通过实例了解Spring中@Profile的作用
# 加载
# 可以使用
# 配置文件
# 它可以
# 都是
# 测试数据
# 眼中
# 这一
# 就会
# 也有
# 让你
# 好了
# 放在
# 还可以
# 多个
# 是这样
# 有很多
# 还能
# 说什么
# 才会
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
b2c电商网站制作流程,b2c水平综合的电商平台?
Python企业级消息系统教程_KafkaRabbitMQ高并发应用
如何用好域名打造高点击率的自主建站?
HTML5建模怎么导出为FBX格式_FBX格式兼容性及导出步骤【指南】
如何快速生成可下载的建站源码工具?
如何在云主机上快速搭建网站?
Laravel如何实现用户密码重置功能?(完整流程代码)
简历在线制作网站免费版,如何创建个人简历?
如何在云服务器上快速搭建个人网站?
如何快速配置高效服务器建站软件?
Python制作简易注册登录系统
Laravel如何实现API速率限制?(Rate Limiting教程)
深圳防火门网站制作公司,深圳中天明防火门怎么编码?
Laravel如何记录日志_Laravel Logging系统配置与自定义日志通道
Win11搜索不到蓝牙耳机怎么办 Win11蓝牙驱动更新修复【详解】
电商网站制作多少钱一个,电子商务公司的网站制作费用计入什么科目?
php 三元运算符实例详细介绍
JavaScript如何实现错误处理_try...catch如何捕获异常?
Laravel Fortify是什么,和Jetstream有什么关系
JS碰撞运动实现方法详解
1688铺货到淘宝怎么操作 1688一键铺货到自己店铺详细步骤
iOS发送验证码倒计时应用
如何用低价快速搭建高质量网站?
laravel怎么为应用开启和关闭维护模式_laravel应用维护模式开启与关闭方法
高端智能建站公司优选:品牌定制与SEO优化一站式服务
EditPlus中的正则表达式 实战(4)
黑客入侵网站服务器的常见手法有哪些?
使用豆包 AI 辅助进行简单网页 HTML 结构设计
Laravel怎么配置不同环境的数据库_Laravel本地测试与生产环境动态切换【方法】
香港服务器网站搭建教程-电商部署、配置优化与安全稳定指南
如何在服务器上配置二级域名建站?
iOS正则表达式验证手机号、邮箱、身份证号等
如何快速查询域名建站关键信息?
大连企业网站制作公司,大连2025企业社保缴费网上缴费流程?
zabbix利用python脚本发送报警邮件的方法
Laravel如何配置中间件Middleware_Laravel自定义中间件拦截请求与权限校验【步骤】
在线制作视频的网站有哪些,电脑如何制作视频短片?
jQuery 常见小例汇总
非常酷的网站设计制作软件,酷培ai教育官方网站?
如何用IIS7快速搭建并优化网站站点?
Laravel如何与Docker(Sail)协同开发?(环境搭建教程)
如何快速搭建高效简练网站?
网站制作报价单模板图片,小松挖机官方网站报价?
如何在HTML表单中获取用户输入并结合JavaScript动态控制复利计算循环
Python高阶函数应用_函数作为参数说明【指导】
如何在IIS7中新建站点?详细步骤解析
Python面向对象测试方法_mock解析【教程】
Laravel中的withCount方法怎么高效统计关联模型数量
PHP正则匹配日期和时间(时间戳转换)的实例代码
MySQL查询结果复制到新表的方法(更新、插入)

