在应用部署的时候,往往遇到需要发布到不同环境的情况,而每个环境的数据库信息、密钥信息等可能会存在差异。
多环境文件目录(src/main/resources):
//开发环境
application-dev.properties
//生产环境
application-prod.properties
//主文件
application.properties
一. 打包
Springboot式
1 默认环境
1.1在application.properties里面指定默认环境名称:
spring.profiles.active=dev
1.2 cmd(或直接进入目录右键)进入到项目根目录下执行命令:
// -e为显示可能出现的异常详细信息 -U为强制让Maven检查所有SNAPSHOT依赖更新,确保集成基于最新的状态,如果没有该参数,Maven默认以天为单位检查更新
mvn clean package –Dmaven.test.skip=true -e –U
2 指定环境
2.1 在application.properties里面指定动态环境变量(spring.profiles名称自定义):
spring.profiles.active=@spring.profiles@
2.2 cmd进入到项目根目录下执行命令:
// dev为指定环境名称
mvnclean packge –Dmaven.test.skip=true -Dspring.profiles=dev
注意:
1不能去除定环境部分(-Dspring.profiles=dev),如去除打出的包不能正常运行。
2 mvn clean packge –Dmaven.test.skip=true -Pdev 打出的包无法正常运行。
Maven式
默认和指定环境
1 pom.xml文件内容配置:
<profiles>
<profile>
<id>dev</id>
<properties>
<profileActive>dev</profileActive>
</properties>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<profile>
<id>prod</id>
<properties>
<profileActive>prod</profileActive>
</properties>
</profile>
</profiles>
<build>
<finalName>projectName</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<!-- 最佳实践:避免 devtools传递性的被应用到项目中其他的 module -->
<fork>true</fork>
<!-- springboot 的唯一main启动类方法的入口,如此部分省略,当程序中有其它测试main方法时,程序将因找到多启动类而无法正常启动 -->
<mainClass>com.em.Application</mainClass>
</configuration>
</plugin>
</plugins>
</build>
// profileActive名称可更改,如更改pom对应的改名称也需进行同名更改。
2 在application.properties里面指定动态环境变量
spring.profiles.active=@profileActive@
3 cmd进入到项目根目录下执行命令
//-P和环境名称之间空格可有可无
mvnclean packge –Dmaven.test.skip=true -Pdev
注意:
1 在属性文件中替换变量时,应使用@符号,使用$符号,无法替换,原因是maven的maven-resources-plugin可以定义这个替换的符号。通过eclipse提供的Maven Pom editor编辑器打开pom.xml文件,在“Effective POM”选项卡中,可以看到定义的是@这个符号
2 怎么在启动springboot应用时,打印正在使用的profile,避免配置错误呢?可以参考如下代码:
public static void main(String[] args) {
ApplicationContextctx = SpringApplication.run(RestApiApplication.class, args);
String[]activeProfiles = ctx.getEnvironment().getActiveProfiles();
for(String profile : activeProfiles) {
logger.warn("SpringBoot 使用profile为:{}" , profile);
}
}
见:
https://blog.csdn.net/lihe2008125/article/details/50443491
https://blog.csdn.net/rtuujnncc/article/details/78249146?locationNum=9&fps=1
https://www.jianshu.com/p/b74283e5fe3a
二. 运行
1 Jar
// 后可跟任意application.properties里变量,以—(双横)开始
java -jar app.jar--spring.profiles.active=dev –server.port=8888
2 War
// 打war包在容器中运行(tomcat)
2.1 将packaging改为war
2.2 将内置tomcat依赖包去除(防止该依赖包内容和容器tomcat内容冲突)
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
2.3 springboot应用servlet初始化
package com.rz;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.support.SpringBootServletInitializer;
import com.rz.Application;
public class ApplicationServletInitializer extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder.sources(Application.class);
}
}
2.4 进行打包操作,见上打包项。
3 spring-boot:run
3.1 maven式
启动指定Profile通过-P,如mvn spring-boot:run -Pdev
3.2 spring-boot式
启动指定spring-boot的spring.profiles.active
mvn spring-boot:run -Drun.profiles=dev
4 ide
运行Application.java文件启动,则增加参数--spring.profiles.active=dev
(如在application.properties配置默认环境,此参数在不用在ide中配置)
见 :
http://www.jspxcms.com/knowledge/341.html
三. 高级应用
在某些情况下,应用的某些业务逻辑可能需要有不同的实现。例如邮件服务,假设EmailService中包含的send(String email)方法向指定地址发送电子邮件,但是我们仅仅希望在生产环境中才执行真正发送邮件的代码,而开发环境里则不发送以免向用户发送无意义的垃圾邮件。
我们可以借助Spring的注解@Profile实现这样的功能,这样需要定义两个实现EmailService借口的类:
/**
* 发送邮件接口
*/
public interface EmailService {
/**发送邮件*/
publicvoid send();
}
1 发送邮件的具体实现(dev-开发环境的代码):
@Service
@Profile("dev") //开发环境的时候
public class DevEmailServiceImpl implementsEmailService{
@Override
publicvoid send() {
System.out.println("DevEmailServiceImpl.send().开发环境不执行邮件的发送.");
}
}
2 发送邮件的具体实现(prod-生产环境的代码):
@Service
@Profile("prod") //生产环境
public class ProdEmailServiceImpl2implements EmailService{
@Override
publicvoid send() {
System.out.println("DevEmailServiceImpl.send().生产环境执行邮件的发送.");
//具体的邮件发送代码.
//mail.send();
}
}
@Profile("dev")表明只有Spring定义的Profile为dev时才会实例化DevEmailService这个类。
在application.properties中加入:spring.profiles.active=dev
见:
https://blog.csdn.net/swordsnapliu/article/details/78540902
http://www.leftso.com/blog/111.html
另:普通Maven项目多环境打包:
<profiles>
<profile>
<id>develop</id>
<properties>
<package.environment>develop</package.environment>
</properties>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<build>
<resources>
<resource>
<directory>src/main/resources/develop</directory>
</resource>
</resources>
</build>
</profile>
<profile>
<id>ga</id>
<properties>
<package.environment>ga</package.environment>
</properties>
<build>
<resources>
<resource>
<directory>src/main/resources/ga</directory>
</resource>
</resources>
</build>
</profile>
</profiles>
<!-- 打包部署 -->
<build>
<finalName>projectName</finalName>
<resources>
<resource>
<directory>src/main</directory>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>tomcat-maven-plugin</artifactId>
<version>1.1</version>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
</plugin>
</plugins>
</build>
当环境变动时,环境编译插件检查下载
<!-- 针对环境变动时的环境编译插件的重新下载,一次处理 -->
<pluginRepositories>
<pluginRepository>
<id>nexus_plugin</id>
<name>nexus_plugin</name>
<!-- 镜像地址 http://repo1.maven.org/maven2/ -->
<url>http://maven.aliyun.com/nexus/content/groups/public</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
<repositories>
<repository>
<id>nexus</id>
<name>nexus</name>
<url>http://maven.aliyun.com/nexus/content/groups/public</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>