跳到主要内容
版本:4.0.2

传统部署

QWen Max 中英对照 Traditional Deployment

Spring Boot 支持传统部署方式以及更现代的部署形式。本节解答有关传统部署的常见问题。

创建一个可部署的 War 文件

注意

由于 Spring WebFlux 并不严格依赖于 Servlet API,并且应用程序默认部署在内嵌的 Reactor Netty 服务器上,因此 WebFlux 应用程序不支持 War 部署。

生成可部署的 war 文件的第一步是提供一个 SpringBootServletInitializer 的子类,并重写其 configure 方法。这样做利用了 Spring Framework 对 Servlet 3.0 的支持,使你能够在应用由 servlet 容器启动时对其进行配置。通常,你应该将应用程序的主类修改为继承 SpringBootServletInitializer,如下例所示:

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);
}

}

下一步是更新你的构建配置,使你的项目生成一个 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 的代码替换为对 SpringApplicationSpringApplicationBuilder 的调用。Spring MVC Web 应用程序通常可以先创建一个可部署的 war 应用程序,然后再将其迁移到可执行的 war 或 jar。

要创建一个可部署的 war 文件,可以通过继承 SpringBootServletInitializer(例如,在一个名为 Application 的类中)并添加 Spring Boot 的 @SpringBootApplication 注解,使用类似于以下示例所示的代码:

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;
}

}

请记住,无论你在 sources 中放入什么,它都只是一个 Spring ApplicationContext。通常情况下,任何已经能正常工作的内容在这里也应该能正常工作。你可能会在稍后移除一些 Bean,让 Spring Boot 为其提供自己的默认实现,但在那之前,你应该能够先让某些功能运行起来。

静态资源可以移至 classpath 根目录下的 /public(或 /static/resources/META-INF/resources)。messages.properties 文件同样适用此规则(Spring Boot 会自动在 classpath 根目录下检测该文件)。

直接使用 Spring 的 DispatcherServlet 和 Spring Security 通常无需额外更改。如果你的应用程序中包含其他功能(例如,使用了其他 servlet 或 filter),你可能需要通过替换 web.xml 中的相应元素,在 Application 上下文中添加一些配置,如下所示:

一旦 war 文件可以正常运行,你可以通过在 Application 中添加一个 main 方法使其可执行,如下例所示:

public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
备注

如果你打算将你的应用程序以 war 包形式或可执行应用程序的方式启动,你需要将构建器的自定义配置放在一个方法中,该方法同时对 SpringBootServletInitializer 回调和 main 方法可用,如下所示:

import org.springframework.boot.Banner;
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 builder) {
return customizerBuilder(builder);
}

public static void main(String[] args) {
customizerBuilder(new SpringApplicationBuilder()).run(args);
}

private static SpringApplicationBuilder customizerBuilder(SpringApplicationBuilder builder) {
return builder.sources(MyApplication.class).bannerMode(Banner.Mode.OFF);
}

}

应用程序可以属于多个类别:

  • 没有 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 的典型初始化程序应类似于以下示例:

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 {

}

如果你使用 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>