多环境配置是一件非常重要的事情,在日常开发过程中,我们都会有多套开发环境,比如在本地快速开发自测,然后提交到测试环境让专门的人来测试验收,测试环境验收完毕之后再上线到线上环境提供服务,这是比较标准的开发流程,也相应的需要多套开发环境的配置,本文主要介绍在Spring Boot项目中如何进行多环境配置的方法。
在maven项目中,我们有一种简洁的多环境配置方式,maven的思路是资源文件根据环境进行隔离,在打包的时候去加载正确的配置资源进行配置,使用maven的多环境资源隔离配置,需要在build里面走增加下面的内容
<resources> <resource> <directory>src/main/java</directory> <includes> <include>**/*.xml</include> </includes> </resource> <resource> <directory>src/main/profile/${conf-dir}</directory> </resource> <resource> <directory>src/main/resources</directory> </resource> </resources>
这里的配置主要做的事情就是标记资源文件,我把src/main/profile/公式输入有误{conf-dir}的具体值见下面的配置:
<profiles> <profile> <id>dev</id> <activation> <activeByDefault>true</activeByDefault> </activation> <properties> <conf-dir>dev</conf-dir> </properties> </profile> <profile> <id>test</id> <properties> <conf-dir>test</conf-dir> </properties> </profile> <profile> <id>product</id> <properties> <conf-dir>product</conf-dir> </properties> </profile> </profiles>
在这里设置了三个环境,分别为dev、test和product,分别代表本地开发,测试环境以及线上环境,这样的话,我们在打包的时候使用-P命令即可指定相应的环境资源。maven配置好了之后,需要在src/main/profile/目录下新建三个文件,名字分别叫dev、test和product,然后可以创建一个config.properties文件,里面可以使用key=value的形式配置变量。
在Spring boot项目中,如果想要使用maven的分环境功能,需要额外引入一个Spring的xml文件,具体的做法就是在boot里面使用@ImportResource注解,比如@ImportResource(locations = "classpath:/spring/applicationContext.xml"),这样在classpath:/spring/applicationContext.xml这个文件里面就可以使用具体的环境配置了。下面是xml文件的具体内容:
<?xml version="1.0" encoding="UTF-8" standalone="no"?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd"> <!-- 导入属性配置文件 --> <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="locations"> <list> <value>classpath:config.properties</value> </list> </property> </bean> <bean id="profileCheck" class="io.spring.learn.configures.ProfileCheck"> <property name="env" value="${profile.env}"/> </bean></beans>
在xml里面导入了我们的分环境配置文件,并且在profileCheck bean里面注入了配置文件中的变量。这个时候我们就可以获取相应环境下的变量了。
在Springboot项目中,不建议使用xml的配置,spring boot提供了一种新的分环境功能,具体的做法如下:
(1)、除了原有的application.properties之外,新建三个配置文件,分别叫application-dev.properties,application-test.properties,application-product.properties,分别代表开发环境、测试环境以及线上环境的配置文件。
(2)、在不同环境的配置文件中使用key=value的形式配置变量。
(3)、在bean配置的时候使用${key}的形式来使用配置即可,当然,bean的属性注入有多种方式,可以根据各自的情况去使用合适的方式去注入。
(4)、在执行的时候使用 --spring.profiles.active来指定环境,比如--spring.profiles.active=product指定为线上环境。
下面以一个配置数据源的例子来具体说明一下。写一个新的配置类DataSourceBean:
package io.spring.learn.configures;import com.alibaba.druid.pool.DruidDataSource;import org.springframework.boot.context.properties.ConfigurationProperties;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.Primary;@Configurationpublic class DataSourceBean { @Bean @Primary @ConfigurationProperties(prefix = "datasource") public DruidDataSource getDrudDataSource() { return new DruidDataSource(); } }
可以看到使用 @ConfigurationProperties(prefix = "datasource")来加载配置文件中的属性值,在各个环境的配置文件中分别配置几个数据源属性,比如在开发环境的配置如下:
### datasource datasource.username=root datasource.password=localroot123 datasource.url=jdbc:mysql://127.0.0.1:3306/dev_db?useUnicode=true&characterEncoding=utf8datasource.dbtype=mysql datasource.maxactive=20
写一个Controller来测试效果:
package io.spring.learn.web;import com.alibaba.druid.pool.DruidDataSource;import lombok.AllArgsConstructor;import lombok.Getter;import lombok.Setter;import lombok.ToString;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import org.springframework.web.bind.annotation.RestController;@RestController@RequestMapping(value = "/api/db/source")public class DataSourceController { @Autowired private DruidDataSource druidDataSource; @RequestMapping(value = "/drud", method = RequestMethod.GET) public DataSourceObject getDruidDataSource() { return new DataSourceObject( druidDataSource.getUsername(), druidDataSource.getPassword(), druidDataSource.getUrl(), druidDataSource.getMaxActive(), druidDataSource.getDbType()); } @Setter @Getter @ToString @AllArgsConstructor private static class DataSourceObject { private String username; private String password; private String url; private int maxActive; private String dbType; } }
为了方便启动项目,写一个脚本execute/sh:
#!/bin/sh./compile.sh && echo 'compile & package project success, start to run it' || echo 'failed to compile or package the project, check your project and re-try'JAR=../target/spring-boot-starter-0.0.1-SNAPSHOT.jarecho "jar location: $JAR"java -jar $JAR --spring.profiles.active=product
compile.sh为:
#!/bin/shcd ../ mvn clean -U package -Ptest -Dmaven.test.skip=true
最后,进入到脚本目录,然后执行execute.sh,就可以启动项目,可以看到在execute.sh中设置了--spring.profiles.active=product,你可以试着改变--spring.profiles.active=product来看最后的效果,比如--spring.profiles.active=product的时候,可以看到Controller返回的json为:
作者:疼蛋之丸
链接:https://www.jianshu.com/p/68cd1d5cb63a