1. 程式人生 > >如何將已有專案遷移到Spring Boot

如何將已有專案遷移到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)。