Spring入门(七):Spring Profile使用讲解
1. 使用场景
在日常的开发工作中,我们经常需要将程序部署到不同的环境,比如Dev开发环境,QA测试环境,Prod生产环境,这些环境下的一些配置肯定是不一样的,比如数据库配置,Redis配置,RabbitMQ配置。
如果每次切换发布环境,都需要修改配置重新构建的话,那对程序员来说将是噩梦,针对这种场景,Spring提供了@Profile注解来实现按照不同的环境装配不同的bean,进而实现程序只需构建一次,但可以部署到多个环境。
2. 配置profile bean
为了更好的理解,我们通过具体的代码示例来理解下Spring profile的使用方法,这里我们以数据库配置为例。
说明:本篇博客的重点是讲解@Profile注解的使用,数据库的操作只是辅助理解@Profile,因此不会讲解的太详细,不过后续会单独写博客讲解
假设我们有3套环境(Dev,QA,Prod),这3套环境的数据库都使用的是mysql,但是其地址,用户名,密码都不一样,那么在Java配置中,该如何声明这些bean呢?
2.1 Java配置中配置profile bean
首先需要了解的是,@Profile注解是从Spring 3.1版本中开始引入的,并且在这个版本中,@Profile注解只能在类级别上使用。
因此我们可以按照环境分别创建数据库配置,如下所示:
Dev环境下的数据库配置:
package chapter03.profile;
import org.apache.commons.dbcp2.BasicDataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import javax.sql.DataSource;
@Configuration
@Profile("dev")
public class DevDataSourceConfig {
@Bean
public DataSource devDataSource() {
System.out.println("This is dev DataSource");
BasicDataSource basicDataSource = new BasicDataSource();
basicDataSource.setDriverClassName("com.mysql.jdbc.Driver");
basicDataSource.setUrl("jdbc:mysql://localhost:3306/mybatis_action_db");
basicDataSource.setUsername("dev");
basicDataSource.setPassword("dev");
return basicDataSource;
}
}
使用上述代码需要在pom.xml中添加如下依赖:
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-dbcp2</artifactId>
<version>2.7.0</version>
</dependency>
注意事项:如果类级别上使用了@Profile("dev"),那么该类中的所有bean都会在profile为dev时创建。
QA环境下的数据库配置:
package chapter03.profile;
import org.apache.commons.dbcp2.BasicDataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import javax.sql.DataSource;
@Configuration
@Profile("qa")
public class QADataSourceConfig {
@Bean
public DataSource qaDataSource() {
System.out.println("This is qa DataSource");
BasicDataSource basicDataSource = new BasicDataSource();
basicDataSource.setDriverClassName("com.mysql.jdbc.Driver");
basicDataSource.setUrl("jdbc:mysql://localhost:3307/mybatis_action_db");
basicDataSource.setUsername("qa");
basicDataSource.setPassword("qa");
return basicDataSource;
}
}
Prod环境下的数据库配置:
package chapter03.profile;
import org.apache.commons.dbcp2.BasicDataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import javax.sql.DataSource;
@Configuration
@Profile("prod")
public class ProdDataSourceConfig {
@Bean
public DataSource prodDataSource() {
System.out.println("This is prod DataSource");
BasicDataSource basicDataSource = new BasicDataSource();
basicDataSource.setDriverClassName("com.mysql.jdbc.Driver");
basicDataSource.setUrl("jdbc:mysql://localhost:3308/mybatis_action_db");
basicDataSource.setUsername("prod");
basicDataSource.setPassword("prod");
return basicDataSource;
}
}
不过从Spring 3.2开始,@Profile注解可以与@Bean注解一起在方法级别上使用。
这也就使得我们可以将刚刚的3个配置类合并成1个配置类(推荐该方式),如下所示:
package chapter03.profile;
import org.apache.commons.dbcp2.BasicDataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import javax.sql.DataSource;
@Configuration
public class DataSourceConfig {
@Bean
@Profile("dev")
public DataSource devDataSource() {
System.out.println("This is dev DataSource");
BasicDataSource basicDataSource = new BasicDataSource();
basicDataSource.setDriverClassName("com.mysql.jdbc.Driver");
basicDataSource.setUrl("jdbc:mysql://localhost:3306/mybatis_action_db");
basicDataSource.setUsername("dev");
basicDataSource.setPassword("dev");
return basicDataSource;
}
@Bean
@Profile("qa")
public DataSource qaDataSource() {
System.out.println("This is qa DataSource");
BasicDataSource basicDataSource = new BasicDataSource();
basicDataSource.setDriverClassName("com.mysql.jdbc.Driver");
basicDataSource.setUrl("jdbc:mysql://localhost:3307/mybatis_action_db");
basicDataSource.setUsername("qa");
basicDataSource.setPassword("qa");
return basicDataSource;
}
@Bean
@Profile("prod")
public DataSource prodDataSource() {
System.out.println("This is prod DataSource");
BasicDataSource basicDataSource = new BasicDataSource();
basicDataSource.setDriverClassName("com.mysql.jdbc.Driver");
basicDataSource.setUrl("jdbc:mysql://localhost:3308/mybatis_action_db");
basicDataSource.setUsername("prod");
basicDataSource.setPassword("prod");
return basicDataSource;
}
}
注意事项:没有指定profile的bean始终都会创建,与激活哪个profile无关。
2.2 xml中配置profile bean
我们也可以通过<beans>元素的profile属性,在xml中配置profile bean,如下所示:
<?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:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"
profile="dev">
<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource"
p:driverClassName="com.mysql.jdbc.Driver"
p:url="jdbc:mysql://localhost:3306/mybatis_action_db"
p:username="dev"
p:password="dev"/>
</beans>
可以参考该配置,分别创建qa和prod环境的profile xml文件。
不过还是推荐使用嵌套的<beans>元素,在一个xml文件中配置好3个环境的数据源,代码如下所示:
<?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:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<beans profile="dev">
<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource"
p:driverClassName="com.mysql.jdbc.Driver"
p:url="jdbc:mysql://localhost:3306/mybatis_action_db"
p:username="dev"
p:password="dev"/>
</beans>
<beans profile="qa">
<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource"
p:driverClassName="com.mysql.jdbc.Driver"
p:url="jdbc:mysql://localhost:3307/mybatis_action_db"
p:username="qa"
p:password="qa"/>
</beans>
<beans profile="prod">
<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource"
p:driverClassName="com.mysql.jdbc.Driver"
p:url="jdbc:mysql://localhost:3308/mybatis_action_db"
p:username="prod"
p:password="prod"/>
</beans>
</beans>
3. 激活profile
截止目前,我们按照环境的维度创建了3个bean,但实际运行时,只会创建1个bean,具体创建哪个bean取决于处于激活状态的是哪个profile。
那么,我们该如何激活某个profile呢?
Spring在确定激活哪个profile时,需要依赖2个属性:
- spring.profiles.active
- spring.profiles.default
spring.profiles.active的优先级比spring.profiles.default高,即如果没有配置spring.profiles.active,就使用spring.profiles.default配置的值,如果配置了spring.profiles.active,就不会再使用spring.profiles.default配置的值。
如果两者都没有配置,就只会创建那些没有定义profile的bean。
Web应用中,在web.xml中设置spring.profiles.active的代码如下所示:
<context-param>
<param-name>spring.profiles.active</param-name>
<param-value>dev</param-value>
</context-param>
也可以使用代码方式激活:
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.getEnvironment().setActiveProfiles("dev");
4. 单元测试
新建Main类,在其main()方法中添加如下测试代码:
package chapter03.profile;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Main {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.getEnvironment().setActiveProfiles("dev");
context.register(DataSourceConfig.class);
context.refresh();
context.close();
}
}
输出结果如下所示:
This is dev DataSource
如果将代码修改为context.getEnvironment().setActiveProfiles("qa");,输出结果为:
This is qa DataSource
如果将代码修改为context.getEnvironment().setActiveProfiles("prod");,输出结果为:
This is prod DataSource
5. 源码及参考
源码地址:https://github.com/zwwhnly/spring-action.git,欢迎下载。
汪云飞《Java EE开发的颠覆者:Spring Boot实战》
Craig Walls 《Spring实战(第4版)》
Spring入门(七):Spring Profile使用讲解的更多相关文章
- spring入门(七) spring mvc+mybatis+generator
1.Mybatis-Generator下载 地址:https://github.com/mybatis/generator/releases 我使用的是 mybatis-generator-core- ...
- Spring系列(七) Spring MVC 异常处理
Servlet传统异常处理 Servlet规范规定了当web应用发生异常时必须能够指明, 并确定了该如何处理, 规定了错误信息应该包含的内容和展示页面的方式.(详细可以参考servlet规范文档) 处 ...
- 从零开始学spring cloud(七) -------- Spring Cloud OpenFegin
一.OpenFegin 介绍 Feign是一个声明性的Web服务客户端. 它使编写Web服务客户端变得更容易. 要使用Feign,请创建一个界面并对其进行注释. 它具有可插入的注释支持,包括Feign ...
- spring学习七 spring和dynamic project进行整合
spring和web项目进行整合,其实就是在项目启动时,就创建spring容器,然后在servlet中使用spring容器进行开. 注意:为了页面可以访问到servlet,因此servlet必须放进t ...
- Spring学习(七)-----Spring Bean的5种作用域
在Spring中,bean作用域用于确定哪种类型的 bean 实例应该从Spring容器中返回给调用者.bean支持的5种范围域: 单例(singleton) - 每个Spring IoC 容器返回一 ...
- spring入门(六) spring mvc+mybatis
1.引入依赖 <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis --> <dependency> < ...
- spring入门(五) spring mvc+hibernate
核心是让SessionFactory由Spring管理 1.引入依赖 <!-- https://mvnrepository.com/artifact/org.springframework/sp ...
- spring入门(四) spring mvc返回json结果
前提:已搭建好环境 1.建立Controller package com.ice.controller; import com.ice.model.Person; import org.springf ...
- Spring学习(七)--Spring MVC的高级技术
一.Spring MVC配置的替代方案 我们已经了解如何通过AbstractAnnotationConfigDispatcherServlet- Initializer快速搭建了Spring MVC环 ...
随机推荐
- JAVA超级简单的爬虫例子(1)
爬取整个页面的数据,并进行有效的提取信息,注释都有就不废话了: public class Reptile { public static void main(String[] args) { Stri ...
- 绝对是全网最好的Splay 入门详解——洛谷P3369&BZOJ3224: Tyvj 1728 普通平衡树 包教包会
平衡树是什么东西想必我就不用说太多了吧. 百度百科: 一个月之前的某天晚上,yuli巨佬为我们初步讲解了Splay,当时接触到了平衡树里的旋转等各种骚操作,感觉非常厉害.而第二天我调Splay的模板竟 ...
- .NET Core 学习资料精选:入门
开源跨平台的.NET Core,还没上车的赶紧的,来不及解释了-- 本系列文章,主要分享一些.NET Core比较优秀的社区资料和微软官方资料.我进行了知识点归类,让大家可以更清晰的学习.NET Co ...
- PYTHONIOENCODING = UTF-8 引发的血案
血案: 我就是想在Jenkins上运行一段自动化python代码,就是最简单的本地控制台输出, 我就不懂了它为什么一直是去找 cp1252.py 编码???目前, 确定 pycharm 运行脚本很OK ...
- 如何在vue中使用echart
1.安装echarts依赖 npm install echarts --save 2.在main.js中全局中引用 import echarts from 'echarts' Vue.protot ...
- Scrum 使用絮叨
关于Scrum 的一些絮叨 Scrum 的推行的基础在于全员参与,全员协作,包含Dev, QA(quality assurance) ,BA(Business analyst)以及Supporter ...
- Netty-Pipeline深度解析
首先我们知道,在NIO网络编程模型中,IO操作直接和channel相关,比如客户端的请求连接,或者向服务端发送数据, 服务端都要从客户端的channel获取这个数据 那么channelPipeline ...
- GO学习笔记 - 命令行解析
本文主题:基于os.Args与flag实现Golang命令行解析. 小慢哥的原创文章,欢迎转载 目录 ▪ 一. os.Args ▪ 二. flag ▪ 三. 结合os.Args与flag实现子命令 ▪ ...
- cve-2018-2893 WebLogic
最近爆出来了新的漏洞cve-2018-2893 一.背景介绍 WebLogic是美国Oracle公司出品的一个Application Server,确切的说是一个基于JAVAEE架构的中间件,WebL ...
- Excel催化剂开源第2波-自动检测Excel的位数选择对应位数的xll文件安装
Excel插件的部署问题难倒了不了的用户,特别是VSTO的部署,用ExcelDna开发的xll文件部署方便,不挑用户机器环境,是其开发Excel插件的一大优势. 其开发出来的xll文件,最终还是需要考 ...