8.部署 Spring Boot
谈到部署 Spring Boot 应用,这里介绍两种部署的方式:jar方式
和war方式
。除此之外还会补充说明多环境部署
需要注意的地方。
jar方式
Spring Boot 应用默认采用 jar
形式方式打包,可以通过Maven进行打包插件配置。
<!-- Package as an executable jar -->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
在pom文件中添加上述Maven插件之后,在项目应用目录下运行命令:mvn package
,
该命令会将项目应用打包生成jar文件并保存在项目target目录下。
在打包完成后,可以通过以下命令运行打包好的jar文件:
java -jar target/xxx.jar
至此,我们就可以将jar包部署在服务器上运行了。这个时候需要注意,有些情况下运行需要传入端口、数据库连接密码等信息,我们可以对上面的命令稍作修改继续执行。
java -jar target/xxx.jar --server.port=8090
--spring.datasource.password=bcxtm77
war方式
在之前的文章提到过,Spring Boot 应用是胶水,内置集成了很多组件,内置Tomcat就是其中的一种。
由于内置了Tomcat,我们可以通过打包为jar的形式进行应用部署。那么对于服务端的部署、容器不是Tomcat的情况【Jetty服务器等其他方式】,我们就需要将应用打包为war包形式,部署到其他运行容器中了。
四个步骤
-
在(父)pom文件中将打包方式变更为:war
<packaging>war</packaging>
-
剥除内置Tomcat依赖:scope 变更为 provided
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> <scope>provided</scope> </dependency>
-
修改启动类:启动类继承SpringBootServletInitializer类,并重载其configure方法
@SpringBootApplication public class Application extends SpringBootServletInitializer { @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { return application.sources(Application.class); } public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
-
打包命令:mvn package
注:以上方式适合Servlet3.0的web容器,并且对Tomcat7、Jetty9等常用web服务器均适用。
这里多说一嘴:针对笔者经常使用的Tomcat容器,有一些部署上需要注意的地方。
1. war包的文件名默认在Tomcat容器中会作为访问路径的一部分出现,此种情况可以通过将war包解压后的文件夹内容复制到Tomcat9/webapps/ROOT 解决。该做法只可解决该容器中运行单项目情况,多项目不建议采取上述方法。
2. Tomcat默认的运行端口为8080,需要更改可到 Tomcat9/conf/server.xml中进行更改。
多环境部署相关
写在开头,当前快速开发的Spring Boot应用大都会存在两种及以上运行环境:线上环境、开发环境等。那么问题来了,不同环境对应不同的配置要求,什么数据库访问地址、用户密码、日志配置【一般线上环境日志为INFO类型】、各种测试功能开关等诸多配置,每次运行都要改一大堆配置参数岂不是很麻烦。
在Spring Boot应用中,配置属性都放到了 application.properties 文件中了。并且,允许多个配置文件共存。在部署应用时,指定哪一个配置文件覆盖 application.properties 即可啦。
如何做呢?
1. 在 resources
目录下创建 application-{profile}.properties 的配置文件。profile名字可以根据项目实际环境进行命名,比如:application-test.properties
- test:测试
- prod:线上
- pre-prod:预发布
- demo:演示
- …
2. 按照jar方式进行运行时,我们可以指定配置文件:
java -jar -Dspring.profiles.active=test target/xxx.jar
按照上述配置执行jar文件后,应用将自动读取 resources/application-test.properties 配置文件,覆盖默认的 application.properties 啦。
3. 为了安全考虑,多环境部署中可能存在 resources 目录没有对应配置文件的情况。可以将配置文件放到指定位置中,采用 spring.config.location
进行指定目录。
java -jar -Dspring.config.location=file:bc/
-Dspring.profiles.active=test target/xxx.jar
Spring Boot 应用默认搜索 classpath:/
、classpath:/config/
、file:./
、file:./config/
目录下是否存在 application.properties 文件。该默认路径优先级由低到高。
以上相关属性配置均出现在类 ConfigFileApplicationListener
中,如图:
4. 关于 @Profile
注解
系统属性:spring.profiles.active
可以指定使用哪个配置文件。比如:
spring.profiles.active=test
则,application-test.properties 将会覆盖 application.properties
此外,@Profile
可以和 @Configuration
、@Component
一起使用,决定配置类是否生效。
@Configuration
public class DataSourceConf {
// 测试环境数据连接池配置
@Bean(name = "dataSource")
@Profile("test")
public DataSource testDatasource(Environment env) {
HikariDataSource test = getDataSource(env);
test.setMaximumPoolSize(10);
return test;
}
// 线上环境数据连接池配置
@Bean(name = "dataSource")
@Profile("prod")
public DataSource prodSource(Environment env) {
HikariDataSource prod = getDataSource(env);
prod.setMaximumPoolSize(100);
return prod;
}
private HikariDataSource getDataSource(Environment env){
//配置数据源参数省略
return ds;
}
}
@Profile
注解还支持使用多种 profile
,并且可以通过 !
来排除特定 profile
,比如:
@Profile({"test", "prod"}) 测试和线上环境均有效
@Profile({"test", "!prod"}) 测试环境有效、线上环境无效