传统部署
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 文件,并将提供的依赖项打包到一个 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 或 filter),您可能需要将 Application 上下文中的这些元素替换为 web.xml 中的元素,如下所示:
-
一个类型为
@Bean的Servlet或ServletRegistrationBean会像在web.xml中的<servlet/>和<servlet-mapping/>一样将该 bean 安装到容器中。 -
一个类型为
@Bean或Filter的FilterRegistrationBean的行为类似(作为<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>