> For the complete documentation index, see [llms.txt](https://jack80342.gitbook.io/spring-boot/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://jack80342.gitbook.io/spring-boot/ix.-how-to-guides/87.-traditional-deployment/87.3-convert-an-existing-application-to-spring-boot.md).

# 87.3 将现有的应用转换为Spring Boot

对于一个非web项目，转换为Spring Boot应用很容易（抛弃创建`ApplicationContext`的代码，取而代之的是调用`SpringApplication`或`SpringApplicationBuilder`）。Spring MVC web应用通常先创建一个可部署的war应用，然后将它迁移为一个可执行的war或jar。建议阅读[Getting Started Guide on Converting a jar to a war.](https://spring.io/guides/gs/convert-jar-to-war/)。

通过继承`SpringBootServletInitializer`创建一个可执行war（比如，在一个名为`Application`的类中），然后添加Spring Boot的`@SpringBootApplication`注解，示例：

```java
@SpringBootApplication
public class Application 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 (via @SpringBootApplication)
        // we actually don't need to override this method.
        return application;
    }

}
```

记住不管你往`sources`放什么东西，它仅是一个Spring `ApplicationContext`，正常情况下，任何生效的在这里也会起作用。有一些beans你可以先移除，然后让Spring Boot提供它的默认实现，不过有可能需要先完成一些事情。

静态资源可以移到classpath根目录下的`/public`（或`/static`，`/resources`，`/META-INF/resources`）。同样的方式也适合于`messages.properties`（Spring Boot在classpath根目录下自动发现这些配置）。

美妙的（Vanilla usage of）Spring `DispatcherServlet`和Spring Security不需要改变。如果你的应用有其他特性，比如使用其他servlets或filters，那你可能需要添加一些配置到你的`Application`上下文中，按以下操作替换`web.xml`的那些元素：

* 在容器中安装一个`Servlet`或`ServletRegistrationBean`类型的`@Bean`，就好像`web.xml`中的`<servlet/>`和`<servlet-mapping/>`。
* 同样的添加一个`Filter`或`FilterRegistrationBean`类型的`@Bean`（类似于`<filter/>`和`<filter-mapping/>`）。
* 在XML文件中的`ApplicationContext`可以通过`@ImportResource`添加到你的`Application`中。简单的情况下，大量使用注解配置可以在几行内定义`@Bean`定义。

一旦war可以使用，我们就通过添加一个main方法到`Application`来让它可以执行，比如：

```java
public static void main(String[] args) {
    SpringApplication.run(Application.class, args);
}
```

**注** 如果你想要把你的应用作为war或者可执行的应用来启动，你需要在一个方法里面共享构建器的配置。那个方法要对`SpringBootServletInitializer`回调和`main`方法都可用，就像这样:

```java
@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);
    }

}
```

应用可以划分为多个类别：

* 没有web.xml的Servlet 3.0+应用
* 有web.xml的应用
* 有上下文层次的应用
* 没有上下文层次的应用

所有这些都可以进行适当的转化，但每个可能需要稍微不同的技术。

Servlet 3.0+的应用转化的相当简单，如果它们已经使用Spring Servlet 3.0+初始化器辅助类。通常所有来自一个存在的`WebApplicationInitializer`的代码可以移到一个`SpringBootServletInitializer`中。如果一个存在的应用有多个`ApplicationContext`（比如，如果它使用`AbstractDispatcherServletInitializer`），那你可以将所有上下文源放进一个单一的`SpringApplication`。你遇到的主要难题可能是如果那样不能工作，那你就要维护上下文层次。参考示例[entry on building a hierarchy](https://docs.spring.io/spring-boot/docs/2.0.0.RELEASE/reference/htmlsingle/#howto-build-an-application-context-hierarchy)。一个存在的包含web相关特性的父上下文通常需要分解，这样所有的`ServletContextAware`组件都处于子上下文中。

对于还不是Spring应用的应用来说，上面的指南有助于你把应用转换为一个Spring Boot应用。然而，你可能会遇到一些问题。在这种情况下，我们建议[使用spring-boot标签在Stack Overflow上提问](https://stackoverflow.com/questions/tagged/spring-boot)。


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://jack80342.gitbook.io/spring-boot/ix.-how-to-guides/87.-traditional-deployment/87.3-convert-an-existing-application-to-spring-boot.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
