转 通过 spring 容器内建的 profile 功能实现开发环境、测试环境、生产环境配置自动切换
spring允许我们通过定义 profile 来将若干不同的 bean 定义组织起来,从而实现不同环境自动激活不同的 profile 来切换配置参数的功能,下面介绍以 xml 的方式定义 profile、如何激活 profile以及定义默认的 profile,整个过程我以配置不同环境的数据源为例,为了简化配置,这里假设只有开发和生产两个环境。
数据源定义为
- <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
- <property name="user" value="${jdbc.user}" />
- <property name="password" value="${jdbc.password}" />
- <property name="jdbcUrl" value="${jdbc.jdbcUrl}" />
- <property name="driverClass" value="${jdbc.driverClass}" />
- <property name="initialPoolSize" value="${c3p0.initialPoolSize}"/>
- <property name="acquireIncrement" value="${c3p0.acquireIncrement}"/>
- <property name="minPoolSize" value="${c3p0.minPoolSize}"/>
- <property name="maxIdleTime" value="${c3p0.maxIdleTime}"/>
- <property name="idleConnectionTestPeriod" value="${c3p0.idleConnectionTestPeriod}" />
- <property name="preferredTestQuery" value="${c3p0.preferredTestQuery}"/>
- </bean>

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="user" value="${jdbc.user}" />
<property name="password" value="${jdbc.password}" />
<property name="jdbcUrl" value="${jdbc.jdbcUrl}" />
<property name="driverClass" value="${jdbc.driverClass}" />
<property name="initialPoolSize" value="${c3p0.initialPoolSize}"/>
<property name="acquireIncrement" value="${c3p0.acquireIncrement}"/>
<property name="minPoolSize" value="${c3p0.minPoolSize}"/>
<property name="maxIdleTime" value="${c3p0.maxIdleTime}"/>
<property name="idleConnectionTestPeriod" value="${c3p0.idleConnectionTestPeriod}" />
<property name="preferredTestQuery" value="${c3p0.preferredTestQuery}"/>
</bean>
classpath下外部资源文件有两个 settings-development.properties 和 settings-production.properties,分别是开发环境和生产环境的数据源配置参数,内容如下
settings-development.properties
- jdbc.user=root
- jdbc.password=111111
- jdbc.driverClass=com.mysql.jdbc.Driver
- jdbc.jdbcUrl=jdbc:mysql://localhost:3306/xxx
- c3p0.minPoolSize=5
- c3p0.initialPoolSize=5
- c3p0.acquireIncrement=5
- c3p0.maxIdleTime=3600
- c3p0.idleConnectionTestPeriod=3600
- c3p0.preferredTestQuery=select 1

jdbc.user=root
jdbc.password=111111
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.jdbcUrl=jdbc:mysql://localhost:3306/xxx
c3p0.minPoolSize=5
c3p0.initialPoolSize=5
c3p0.acquireIncrement=5
c3p0.maxIdleTime=3600
c3p0.idleConnectionTestPeriod=3600
c3p0.preferredTestQuery=select 1
settings-production.properties
- jdbc.user=xxx
- jdbc.password=xxxx
- jdbc.driverClass=com.mysql.jdbc.Driver
- jdbc.jdbcUrl=jdbc:mysql:///xxx
- c3p0.minPoolSize=20
- c3p0.initialPoolSize=20
- c3p0.acquireIncrement=10
- c3p0.maxIdleTime=3600
- c3p0.idleConnectionTestPeriod=3600
- c3p0.preferredTestQuery=select 1

jdbc.user=xxx
jdbc.password=xxxx
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.jdbcUrl=jdbc:mysql:///xxx
c3p0.minPoolSize=20
c3p0.initialPoolSize=20
c3p0.acquireIncrement=10
c3p0.maxIdleTime=3600
c3p0.idleConnectionTestPeriod=3600
c3p0.preferredTestQuery=select 1
1. 定义 profile
现在就可以通过定义 profile 来将开发和生产环境的数据源配置分开,这里我们定义两个 profile,一个名称是 development,另一个名称是 production
- <!-- 开发环境配置文件 -->
- <beans profile="development">
- <context:property-placeholder location="classpath:settings-development.properties"/>
- </beans>
- <!-- 生产环境配置文件 -->
- <beans profile="production">
- <context:property-placeholder location="classpath:settings-production.properties"/>
- </beans>

<!-- 开发环境配置文件 -->
<beans profile="development">
<context:property-placeholder location="classpath:settings-development.properties"/>
</beans> <!-- 生产环境配置文件 -->
<beans profile="production">
<context:property-placeholder location="classpath:settings-production.properties"/>
</beans>
2. 定义默认 profile
默认 profile 是指在没有任何 profile 被激活的情况下,默认 profile 内定义的内容将被使用,通常可以在 web.xml 中定义全局 servlet 上下文参数 spring.profiles.default 实现,代码如下
- <!-- 配置spring的默认profile -->
- <context-param>
- <param-name>spring.profiles.default</param-name>
- <param-value>development</param-value>
- </context-param>

<!-- 配置spring的默认profile -->
<context-param>
<param-name>spring.profiles.default</param-name>
<param-value>development</param-value>
</context-param>
3. 激活 profile
spring 为我们提供了大量的激活 profile 的方法,可以通过代码来激活,也可以通过系统环境变量、JVM参数、servlet上下文参数来定义 spring.profiles.active 参数激活 profile,这里我们通过定义 JVM 参数实现。 在生产环境中,以 tomcat 为例,我们在 tomcat 的启动脚本中加入以下 JVM 参数
- -Dspring.profiles.active="production"

-Dspring.profiles.active="production"
而开发环境中不需要定义该参数,如果不定义,则会使用我们指定的默认 profile ,在这里也就是名称为 development 的 profile。这样当项目部署到不同的环境时,便可以通过 JVM 参数来实现不同环境 profile 自动激活。
4. 延伸
该参数还可以延伸,以至于我们可以在 java 代码中继续通过该参数来区分不同的环境,从而执行不同的操作,代码如下
public class Config { public static String ENV = "development"; } public class InitConfigListener implements ServletContextListener { public void contextInitialized(ServletContextEvent sce) { //侦测jvm环境,并缓存到全局变量中 String env = System.getProperty("spring.profiles.active"); if(env == null) { Config.ENV = "development"; } else { Config.ENV = env; } } } 在项目初始化时获取到该参数后,我们便可以在项目任何位置使用,来执行一些不同环境需要区别对待的操作,例如统计流量的代码只需要在生产环境激活,就可以在jsp中加入如下代码
<!-- 生产环境统计、推送代码 --> <c:if test="${env == 'production' }"> <script> //统计代码 .. </script> </c:if>
转 通过 spring 容器内建的 profile 功能实现开发环境、测试环境、生产环境配置自动切换的更多相关文章
- 【Spring】使用@Profile注解实现开发、测试和生产环境的配置和切换,看完这篇我彻底会了!!
写在前面 在实际的企业开发环境中,往往都会将环境分为:开发环境.测试环境和生产环境,而每个环境基本上都是互相隔离的,也就是说,开发环境.测试环境和生产环境是互不相通的.在以前的开发过程中,如果开发人员 ...
- Spring.profile配合Jenkins发布War包,实现开发、测试和生产环境的按需切换
前两篇不错 Spring.profile实现开发.测试和生产环境的配置和切换 - Strugglion - 博客园https://www.cnblogs.com/strugglion/p/709102 ...
- Spring.profile实现开发、测试和生产环境的配置和切换
软件开发过程一般涉及“开发 -> 测试 -> 部署上线”多个阶段,每个阶段的环境的配置参数会有不同,如数据源,文件路径等.为避免每次切换环境时都要进行参数配置等繁琐的操作,可以通过spri ...
- Spring boot 的profile功能如何实现多环境配置自动切换
通常服务端应用开发需要经过以下几个流程: 开发 -> 测试 -> RC验证 -> 上线 这就涉及到四个不同的环境,开发环境.测试环境.RC环境以及生产环境,为了避免不同环境之间相互干 ...
- Spring Cloud Alibaba学习笔记(7) - Sentinel规则持久化及生产环境使用
Sentinel 控制台 需要具备下面几个特性: 规则管理及推送,集中管理和推送规则.sentinel-core 提供 API 和扩展接口来接收信息.开发者需要根据自己的环境,选取一个可靠的推送规则方 ...
- 深入理解Spring的容器内事件发布监听机制
目录 1. 什么是事件监听机制 2. JDK中对事件监听机制的支持 2.1 基于JDK实现对任务执行结果的监听 3.Spring容器对事件监听机制的支持 3.1 基于Spring实现对任务执行结果的监 ...
- spring容器的refresh方法分析
spring源码版本5.0.5 Spring容器创建之后,会调用它的refresh方法刷新Spring应用的上下文. 首先整体查看AbstractApplicationContext#refresh源 ...
- 【String注解驱动开发】如何按照条件向Spring容器中注册bean?这次我懂了!!
写在前面 当bean是单实例,并且没有设置懒加载时,Spring容器启动时,就会实例化bean,并将bean注册到IOC容器中,以后每次从IOC容器中获取bean时,直接返回IOC容器中的bean,不 ...
- Spring - Spring容器概念及其初始化过程
引言 工作4年多,做了3年的java,每个项目都用Spring,但对Spring一直都是知其然而不知其所以然.鄙人深知Spring是一个高深的框架,正好近期脱离加班的苦逼状态,遂决定从Spring的官 ...
随机推荐
- Elasticsearch Java虚拟机配置详解(转)
引言: 今天,事情终于发生了.Java6(Mustang),是2006年早些时候出来的,至今仍然应用在众多生产环境中,现在终于走到了尽头.已经没有什么理由阻止迁移到Java7(Dolphin)上了. ...
- Mybatis插件原理和PageHelper结合实战分页插件(七)
今天和大家分享下mybatis的一个分页插件PageHelper,在讲解PageHelper之前我们需要先了解下mybatis的插件原理.PageHelper 的官方网站:https://github ...
- c语言_头文件_windows.h
概述 Win32程序的开头都可看到: #include <windows.h> WINDOWS.H是一个最重要的头文件,它包含了其他Windows头文件,这些头文件的某些也包含了其他头文件 ...
- hdu_4824_Disk Schedule(dp)
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=4824 题意:中文,不解释 题解:双调欧几里德旅行商问题,具体可看dp双调欧几里德旅行商,这里注意的是起 ...
- openwrt下加载snmp模块
加snmp模块到openwrt中去 1.下载snmp的解压包文件 net-snmp-5.4.2.1.tar.gz 下载地址为:http://www.net-snmp.org/download.html ...
- 使用AOP 使C#代码更清晰
简介 如果你很熟悉面向方面编程(AOP),你就会知道给代码增加"切面"可以使代码更清晰并且具有可维护性.但是AOP通常都依赖于第三方类库或者硬编码的.net特性来工作.虽然这些实现 ...
- nefu 115 斐波那契的整除
Description 已知斐波那契数列有如下递归定义,f(1)=1,f(2)=1, 且n>=3,f(n)=f(n-1)+f(n-2),它的前几项可以表示为1, 1,2 ,3 ,5 ,8,13, ...
- Linux入门学习教程:虚拟机体验之KVM篇
本文中可以学习到的命令: 1. aptitude 是apt-get 不会产生垃圾的版本 2. dpkg -L virtualbox 显示属于该包的文件 lsmod | grep kvmfi ...
- Entity Framework 学习中级篇2—存储过程(上)
目前,EF对存储过程的支持并不完善.存在以下问题: l EF不支持存储过程返回多表联合查询的结果集. l EF仅支持返回返回某个表的全部字段,以便转换成对应的实体.无法 ...
- c_select 调用参数说明
c_select 调用 1. select系统调用select系统调用是用来让我们的程序监视多个文件描述符的状态变化的.程序会停在select这里等待,直到被监视的文件描述符有某一个或多个发生了状态改 ...