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. 源码及参考
源码地址:,欢迎下载。
汪云飞《java ee开发的颠覆者:spring boot实战》
craig walls 《spring实战(第4版)》
6. 最后
打个小广告,欢迎扫码关注微信公众号:「申城异乡人」,定期分享java技术干货,让我们一起进步。
上一篇: 发布一个自己的jar包给全球人使用
下一篇: python-day14(正式学习)
推荐阅读
-
Spring Boot 入门之消息中间件的使用
-
Spring入门(五):Spring Bean Scope讲解
-
spring cloud 入门系列八:使用spring cloud sleuth整合zipkin进行服务链路追踪
-
Spring入门(十二):Spring MVC使用讲解
-
Spring高级装配,Profile的使用,条件化Bean,解决歧义性
-
spring cloud 入门系列五:使用Feign 实现声明式服务调用
-
idea创建一个入门Spring Boot项目(controller层)使用Moven代码管理
-
Spring入门(十一):Spring AOP使用进阶
-
Spring Boot入门(七):使用MyBatis访问MySql数据库(xml方式)
-
spring cloud 入门系列七:基于Git存储的分布式配置中心--Spring Cloud Config