传统部署
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 容器。 为此,您需要将嵌入式 servlet 容器依赖标记为 provided。
如果您使用 Maven,以下示例将 servlet 容器(在本例中为 Tomcat)标记为 provided:
<dependencies>
<!-- ... -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<!-- ... -->
</dependencies>
如果您使用 Gradle,以下示例将 servlet 容器(在本例中为 Tomcat)标记为 provided:
dependencies {
// ...
providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat'
// ...
}
提示:providedRuntime
优于 Gradle 的 compileOnly
配置。
除其他限制外,compileOnly
依赖项不在测试类路径上,因此任何基于 Web 的集成测试都会失败。
如果您使用 Spring Boot 构建工具插件,将嵌入式 servlet 容器依赖标记为 provided 会生成一个可执行的 war 文件,其中提供的依赖项打包在 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 或过滤器),您可能需要通过替换 web.xml
中的这些元素来向 Application
上下文添加一些配置,如下所示:
-
@Bean
类型的Servlet
或ServletRegistrationBean
将该 bean 安装到容器中,就像它是web.xml
中的<servlet/>
和<servlet-mapping/>
一样。 -
@Bean
类型的Filter
或FilterRegistrationBean
的行为类似(作为<filter/>
和<filter-mapping/>
)。 -
XML 文件中的
ApplicationContext
可以通过@ImportResource
添加到您的Application
中。 或者,在已经大量使用注解配置的情况下,可以用几行@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 或可执行应用程序启动,您需要在 SpringBootServletInitializer
回调和类似以下类中的 main
方法中都可以使用的方法中共享构建器的自定义:
-
Java
-
Kotlin
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);
}
}
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
class MyApplication : SpringBootServletInitializer() {
override fun configure(builder: SpringApplicationBuilder): SpringApplicationBuilder {
return customizerBuilder(builder)
}
companion object {
@JvmStatic
fun main(args: Array<String>) {
customizerBuilder(SpringApplicationBuilder()).run(*args)
}
private fun customizerBuilder(builder: SpringApplicationBuilder): SpringApplicationBuilder {
return builder.sources(MyApplication::class.java).bannerMode(Banner.Mode.OFF)
}
}
}
应用程序可能属于多个类别:
-
没有
web.xml
的 Servlet 3.0+ 应用程序。 -
有
web.xml
的应用程序。 -
有上下文层次结构的应用程序。
-
没有上下文层次结构的应用程序。
所有这些都应该可以转换,但每种情况可能需要稍微不同的技术。
如果已经使用 Spring Servlet 3.0+ 初始化器支持类,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>