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"}) 測試環境有效、線上環境無效