傳統部署
Spring Boot 支援傳統部署以及更現代的部署形式。本節解答了有關傳統部署的常見問題。
建立可部署的 War 檔案
| 由於 Spring WebFlux 不嚴格依賴於 Servlet API,並且應用程式預設部署在嵌入式 Reactor Netty 伺服器上,因此 WebFlux 應用程式不支援 War 部署。 |
生成可部署 war 檔案的第一步是提供一個 SpringBootServletInitializer 子類並重寫其 configure 方法。這樣做利用了 Spring Framework 的 Servlet 3.0 支援,並允許您在 Servlet 容器啟動時配置應用程式。通常,您應該更新應用程式的主類以擴充套件 SpringBootServletInitializer,如以下示例所示
-
Java
-
Kotlin
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
@SpringBootApplication
public class MyApplication extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(MyApplication.class);
}
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.builder.SpringApplicationBuilder
import org.springframework.boot.runApplication
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer
@SpringBootApplication
class MyApplication : SpringBootServletInitializer() {
override fun configure(application: SpringApplicationBuilder): SpringApplicationBuilder {
return application.sources(MyApplication::class.java)
}
}
fun main(args: Array<String>) {
runApplication<MyApplication>(*args)
}
下一步是更新您的構建配置,使您的專案生成 war 檔案而不是 jar 檔案。如果您使用 Maven 和 spring-boot-starter-parent(它為您配置 Maven 的 war 外掛),您只需修改 pom.xml 以將打包更改為 war,如下所示
<packaging>war</packaging>
如果您使用 Gradle,您需要修改 build.gradle 以將 war 外掛應用於專案,如下所示
apply plugin: 'war'
此過程的最後一步是確保嵌入式 Servlet 容器不會干擾部署 war 檔案的 Servlet 容器。
對於 Maven,您需要將嵌入式 Servlet 容器依賴項標記為 provided。例如
<dependencies>
<!-- ... -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<!-- ... -->
</dependencies>
如果您使用 Gradle,您只需將執行時依賴項移到 providedRuntime 配置中。例如
dependencies {
// ...
providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat-runtime'
// ...
}
providedRuntime 優於 Gradle 的 compileOnly 配置。除其他限制外,compileOnly 依賴項不在測試類路徑上,因此任何基於 Web 的整合測試都將失敗。 |
如果您使用 Spring Boot 構建工具外掛,將嵌入式 Servlet 容器依賴項標記為 provided 將生成一個可執行的 war 檔案,其中 provided 依賴項打包在 lib-provided 目錄中。這意味著,除了可以部署到 Servlet 容器之外,您還可以透過在命令列上使用 java -jar 來執行應用程式。
將現有應用程式轉換為 Spring Boot
要將現有非 Web Spring 應用程式轉換為 Spring Boot 應用程式,請替換建立 ApplicationContext 的程式碼,並將其替換為對 SpringApplication 或 SpringApplicationBuilder 的呼叫。Spring MVC Web 應用程式通常適合首先建立可部署的 war 應用程式,然後再將其遷移到可執行的 war 或 jar。
要透過擴充套件 SpringBootServletInitializer(例如,在一個名為 Application 的類中)並新增 Spring Boot @SpringBootApplication 註解來建立可部署的 war,請使用類似於以下示例的程式碼
-
Java
-
Kotlin
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
@SpringBootApplication
public class MyApplication extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
// Customize the application or call application.sources(...) to add sources
// Since our example is itself a @Configuration class (through
// @SpringBootApplication)
// we actually do not need to override this method.
return application;
}
}
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.builder.SpringApplicationBuilder
import org.springframework.boot.runApplication
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer
@SpringBootApplication
class MyApplication : SpringBootServletInitializer() {
override fun configure(application: SpringApplicationBuilder): SpringApplicationBuilder {
// Customize the application or call application.sources(...) to add sources
// Since our example is itself a @Configuration class (through @SpringBootApplication)
// we actually do not need to override this method.
return application
}
}
請記住,您放入 sources 中的任何內容都只是一個 Spring ApplicationContext。通常,任何已經可以工作的東西都應該在這裡工作。您以後可能會刪除一些 bean,並讓 Spring Boot 為它們提供自己的預設值,但在您需要這樣做之前,應該能夠讓某些東西工作起來。
靜態資源可以移動到類路徑根目錄下的 /public(或 /static 或 /resources 或 /META-INF/resources)。messages.properties 也適用(Spring Boot 會自動在類路徑根目錄中檢測到它)。
Spring DispatcherServlet 和 Spring Security 的基本用法應該不需要進一步更改。如果您的應用程式中還有其他功能(例如,使用其他 Servlet 或過濾器),您可能需要向 Application 上下文新增一些配置,透過替換 web.xml 中的這些元素,如下所示
-
型別為
Servlet或ServletRegistrationBean的@Bean會將該 bean 安裝到容器中,就像它在web.xml中是<servlet/>和<servlet-mapping/>一樣。 -
型別為
Filter或FilterRegistrationBean的@Bean行為類似(作為<filter/>和<filter-mapping/>)。 -
XML 檔案中的
ApplicationContext可以透過Application中的@ImportResource新增。或者,已經大量使用註解配置的情況可以通過幾行程式碼重新建立為@Bean定義。
一旦 war 檔案工作正常,您可以透過向 Application 新增 main 方法使其可執行,如以下示例所示
-
Java
-
Kotlin
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
fun main(args: Array<String>) {
runApplication<MyApplication>(*args)
}
|
如果您打算將應用程式作為 war 或可執行應用程式啟動,您需要在一個類中共享構建器的自定義設定,該方法既可用於
|
應用程式可以屬於多個類別
-
沒有
web.xml的 Servlet 3.0+ 應用程式。 -
帶有
web.xml的應用程式。 -
具有上下文層次結構的應用程式。
-
沒有上下文層次結構的應用程式。
所有這些都應該易於轉換,但每個可能需要稍微不同的技術。
如果 Servlet 3.0+ 應用程式已經使用 Spring Servlet 3.0+ 初始化器支援類,那麼它們可能很容易轉換。通常,現有 WebApplicationInitializer 中的所有程式碼都可以移到 SpringBootServletInitializer 中。如果您的現有應用程式有多個 ApplicationContext(例如,如果它使用 AbstractDispatcherServletInitializer),那麼您可能可以將所有上下文源組合到一個 SpringApplication 中。您可能遇到的主要複雜情況是,如果組合不起作用並且您需要維護上下文層次結構。有關示例,請參閱構建層次結構的條目。包含 Web 特定功能的現有父上下文通常需要拆分,以便所有 ServletContextAware 元件都在子上下文中。
尚未是 Spring 應用程式的應用程式可能可以轉換為 Spring Boot 應用程式,前面提到的指導可能會有所幫助。但是,您可能還會遇到問題。在這種情況下,我們建議在 Stack Overflow 上提問,並帶有 spring-boot 標籤。
將 WAR 部署到 WebLogic
要將 Spring Boot 應用程式部署到 WebLogic,您必須確保您的 Servlet 初始化器直接實現 WebApplicationInitializer(即使您擴充套件自已實現它的基類)。
WebLogic 的典型初始化器應類似於以下示例
-
Java
-
Kotlin
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.web.WebApplicationInitializer;
@SpringBootApplication
public class MyApplication extends SpringBootServletInitializer implements WebApplicationInitializer {
}
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer
import org.springframework.web.WebApplicationInitializer
@SpringBootApplication
class MyApplication : SpringBootServletInitializer(), WebApplicationInitializer
如果您使用 Logback,您還需要告訴 WebLogic 優先使用打包版本而不是伺服器預安裝的版本。您可以透過新增一個包含以下內容的 WEB-INF/weblogic.xml 檔案來做到這一點
<?xml version="1.0" encoding="UTF-8"?>
<wls:weblogic-web-app
xmlns:wls="http://xmlns.oracle.com/weblogic/weblogic-web-app"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
https://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd
http://xmlns.oracle.com/weblogic/weblogic-web-app
https://xmlns.oracle.com/weblogic/weblogic-web-app/1.4/weblogic-web-app.xsd">
<wls:container-descriptor>
<wls:prefer-application-packages>
<wls:package-name>org.slf4j</wls:package-name>
</wls:prefer-application-packages>
</wls:container-descriptor>
</wls:weblogic-web-app>