如何將已有專案遷移到Spring Boot
85.1建立可部署的war檔案
生成可部署war檔案的第一步是建立一個 SpringBootServletInitializer的子類並重寫它的configure方法。這樣就可以相容spring Servlet 3.0,允許在servlet容器啟動時配置應用程式。通常這個類需要繼承SpringBootServletInitializer:
@SpringBootApplication
public class Application extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure (SpringApplicationBuilder application) {
return application.sources(Application.class);
}
public static void main(String[] args) throws Exception {
SpringApplication.run(Application.class, args);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
下一步是更新構建配置,以便您的專案生成war檔案而不是jar檔案。如果你使用Maven並使用spring-boot-starter-parent(它為你配置Maven的war外掛),你所需要做的就是修改pom.xml以工程更改為war工程:
<packaging> war </ packaging>
- 1
- 1
如果你使用Gradle,你需要修改build.gradle以將war外掛用到專案中:
apply plugin:'war'
- 1
- 1
最後一步是確保內建的servlet容器不會干擾要部署war檔案的servlet容器。為此,您需要按提供的方式標記內建的servlet容器依賴關係。
Maven:
<dependencies>
<!-- … -->
<dependency>
<groupId>org.springframework.boot</groupId >
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<!-- … -->
</dependencies>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
Gradle:
dependencies {
// ...
providedRuntime'org.springframework.boot :spring-boot-starter-tomcat'
// ...
}
- 1
- 2
- 3
- 4
- 5
- 1
- 2
- 3
- 4
- 5
[注意]
如果您使用的Gradle版本僅支援僅編譯依賴項(2.12或更高版本),則應繼續使用providedRuntime。除了其他限制, compileOnly依賴不在測試類路徑,所以任何基於Web的整合測試將失敗。
如果您使用Spring Boot構建工具,那麼將嵌入式Servlet容器依賴關係標記為已提供將產生一個可執行檔案,並在目錄中打包提供的依賴lib-provided關係。這意味著,除了被部署到一個servlet容器,也可以使用執行應用程式Java
-jar的命令列上。
看一下Spring Boot的示例應用程式,用於上述配置的基於Maven的示例 。
85.2為較早的servlet容器建立可部署的war檔案
較早的Servlet容器不具備的支援ServletContextInitializer中的Servlet 3.0中使用的引導過程。您仍然可以使用彈簧和彈簧引導這些容器,但你將需要一個新增web.xml到您的應用程式並將其配置為載入ApplicationContext通過DispatcherServlet。
85.3將現有應用程式轉換為Spring Boot
對於非web應用程式應該很容易(捨棄程式碼並建立你的 ApplicationContext,並通過呼叫替換為SpringApplication或 SpringApplicationBuilder)。Spring MVC應用程式通常需要先建立可部署的war應用程式,然後將其遷移到可執行的war或jar。jar轉war指南
建立一個繼承自SpringBootServletInitializer(例如,在一個叫做類Application)的可部署war包,並新增Spring Boot的@SpringBootApplication註釋。例:
@SpringBootApplication
public class Application extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
//自定義應用程式或呼叫application.sources(...)新增源
//因為我們的例子本身是一個@Configuration類(通過@SpringBootApplication)
//我們實際上不需要重寫這個方法。
return application;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
記住,無論你放在什麼sources只是一個Spring ApplicationContext,通常已經執行東西都繼續在這裡執行。可能有一些bean你可以以後刪除,讓Spring Boot為它們提供自己的預設值,但某些工作應優先進行。
靜態資源可以移動到/public(或/static或)/resources或 /META-INF/resources)在類路徑根目錄中。messages.properties(Spring Boot在類路徑的根目錄中自動檢測到這一點)也是如此。
Vanilla對Spring DispatcherServlet和Spring Security的使用不需要進一步的修改。如果你的應用程式還有其他特性,如使用其他servlet或過濾器,那麼你需要新增一些配置到Application context,web.xml中替換的標籤如下:
- 一個@Bean類Servlet或者ServletRegistrationBean安裝這個bean在容器中,如果它是一個或。
- 一個@Bean型別Filter或FilterRegistrationBean類似(像a
和。 - 一個ApplicationContext在XML檔案可被新增到一個@Import在
Application。或者已經大量使用註釋配置的簡單情況可以作為定義在幾行中@Bean重新建立。
一旦war包工作,便嚮應用程式中新增一個可執行的main方法,如
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
- 1
- 2
- 3
- 1
- 2
- 3
[注意]
如果打算將應用程式打為war或可執行應用程式,需要共享建設者的自定義中,可以執行SpringBootServletInitializer回撥方法和main方法,就像這樣:
@SpringBootApplication
public class Application extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return configureApplication(builder);
}
public static void main(String[] args) {
configureApplication(new SpringApplicationBuilder()).run(args);
}
private static SpringApplicationBuilder configureApplication(SpringApplicationBuilder builder) {
return builder.sources(Application.class).bannerMode(Banner.Mode.OFF);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
應用程式可以分為多個類別:
- 沒有web.xml的Servlet 3.0+應用程式。
- 帶有web.xml的應用程式。
- 具有上下文層次結構的應用程式。
- 沒有上下文層次結構的應用程式。
所有這些都應該適合轉譯,但每個可能需要略有不同的技巧。
如果已經使用Spring Servlet 3.0+初始化程式支援類,Servlet 3.0+應用程式就很容易轉譯。通常現存在 WebApplicationInitializer上的所有程式碼都可以遷移到SpringBootServletInitializer。如果現有的應用程式有多個ApplicationContext(例如,使用 AbstractDispatcherServletInitializer),那麼可以將所有的上下文源合併為單個SpringApplication。其中可能遇到的問題是,如果程式執行失敗,就需要維護上下文層次結構。請參閱 構建一個層次的條目的例子。包含Web特定功能的現有父上下文通常需要分解,以便所有ServletContextAware元件都在子上下文中。
非Spring應用程式的應用程式會更容易轉換為Spring Boot應用程式,上述指導可能會有所幫助,但過程可能會有所不同。
85.4將WAR部署到WebLogic
要將Spring Boot應用程式部署到WebLogic,必須確保您的servlet初始化程式直接實現WebApplicationInitializer(即使您從已實現它的基類擴充套件)。
WebLogic的典型初始化方法:
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.web.SpringBootServletInitializer;
import org.springframework.web.WebApplicationInitializer;
@SpringBootApplication
public class MyApplication extends SpringBootServletInitializer implements WebApplicationInitializer {
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
如果使用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
http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd
http://xmlns.oracle.com/weblogic/weblogic-web-app
http://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>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
85.5在舊(Servlet 2.5)容器中部署WAR
Spring Boot使用Servlet 3.0 API來初始化ServletContext(暫存器Servlets 等),所以你不能在Servlet 2.5容器外使用相同的應用程式。但是,可以在舊容器上藉助於特殊工具來執行Spring Boot。如果你新增org.springframework.boot:spring-boot-legacy作為依賴(單獨維護 Spring Boot的核心,目前在1.0.2.RELEASE),你所需要做的是建立web.xml並宣告一個context listener、 application context、filters 、servlets 。這個context listener對於Spring Boot是一個特殊的用例,但是對於Servlet 2.5中的Spring應用程式,其餘部分是一般用法。例:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>demo.Application</param-value>
</context-param>
<listener>
<listener-class>org.springframework.boot.legacy.context.web.SpringBootContextLoaderListener</listener-class>
</listener>
<filter>
<filter-name>metricsFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>metricsFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextAttribute</param-name>
<param-value>org.springframework.web.context.WebApplicationContext.ROOT</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>appServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
在這個例子中,我們使用的是單個應用程式上下文(由context listener建立的)並將其連線到DispatcherServlet用一個引數初始化。這在Spring Boot應用程式中是很常見的(一般只有一個application context)。