传统部署
Spring Boot 支持传统部署以及更现代的部署形式。本节解答有关传统部署的常见问题。
创建可部署的 War 文件
由于 Spring WebFlux 不严格依赖于 servlet API,并且应用默认部署在嵌入式 Reactor Netty 服务器上,因此 WebFlux 应用不支持 War 部署。 |
生成可部署的 war 文件的第一步是提供一个 SpringBootServletInitializer
子类并覆盖其 configure
方法。这样做利用了 Spring 框架的 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 容器依赖项标记为已提供。
如果你使用 Maven,以下示例将 servlet 容器(在本例中为 Tomcat)标记为已提供
<dependencies>
<!-- ... -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<!-- ... -->
</dependencies>
如果你使用 Gradle,以下示例将 servlet 容器(在本例中为 Tomcat)标记为已提供
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或过滤器),您可能需要向Application
上下文添加一些配置,方法是替换来自web.xml
的这些元素,如下所示
-
类型为
Servlet
或ServletRegistrationBean
的@Bean
会将该bean安装到容器中,就像它是web.xml
中的<servlet/>
和<servlet-mapping/>
一样。 -
类型为
Filter
或FilterRegistrationBean
的@Bean
的行为类似(作为<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>