【问题标题】:Migrating Spring web application to Spring Boot将 Spring Web 应用程序迁移到 Spring Boot
【发布时间】:2016-02-16 08:52:19
【问题描述】:

我有一个 web 项目,我很容易将它分解到 tomcat 上。事实上,我有一个实现WebApplicationInitializerWebAppInitializer 类(这个类真的很胖),正如您所知,每个支持servlet 3.0 的应用程序服务器都可以轻松检测到它并尝试启动它。现在我想知道是否可以使用 spring boot 启动器并且无需任何进一步的配置,我将我的 WebAppInitializer 传递给它,然后基于我的 WebAppInitializer 启动我的项目的 spring boot?

我只想使用spring-boot的方式在Tomcat上部署应用,不想使用其他spring-boot的工具。

【问题讨论】:

  • 你想要启动但又不想使用它,那何必呢……
  • 非常糟糕的用例

标签: spring spring-boot


【解决方案1】:

是的,这是一个老问题。但我没有看到一个公认的答案,最接近工作答案的答案只有一个指向外部资源的链接。就是这样。

https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-embedded-container-context-initializer

28.4.2 Servlet 上下文初始化

嵌入式 servlet 容器不直接执行 Servlet 3.0+ javax.servlet.ServletContainerInitializer 接口或 Spring 的 org.springframework.web.WebApplicationInitializer 接口。这是 有意的设计决策,旨在降低第三 旨在在战争中运行的党派库可能会破坏 Spring Boot 应用程序。

如果需要在 Spring Boot 中执行 servlet 上下文初始化 应用程序,您应该注册一个实现 org.springframework.boot.web.servlet.ServletContextInitializer 界面。单个 onStartup 方法提供对 ServletContext,如果需要,可以很容易地用作适配器 现有的 WebApplicationInitializer。

扫描 Servlet、过滤器和侦听器

使用嵌入式时 容器,自动注册带有注释的类 @WebServlet、@WebFilter 和 @WebListener 可以通过使用启用 @ServletComponentScan。

[提示] @ServletComponentScan 在独立容器中无效, 而是使用容器的内置发现机制。

我试过了。有效

在我的用例中,我的项目包含几十个 web 应用程序,旨在作为 WAR 在 Tomcat 上运行。许多逻辑被巧妙地设计到 WebApplicationInitializers 中,似乎应该有一种更简单的方法来重用所有这些。将 implements ServletContextInitializer 添加到这些初始化程序并通过 @Configuration 类将它们公开为 bean,从而使用 SpringBoot 的嵌入式 Tomcat 点亮我的网络服务器。

【讨论】:

    【解决方案2】:
    【解决方案3】:

    来自Spring Boot docs

    如果 Servlet 3.0+ 应用程序已经使用 Spring Servlet 3.0+ 初始值设定项支持类,它们可能会很容易转换。通常,现有 WebApplicationInitializer 中的所有代码都可以移动到 SpringBootServletInitializer 中。如果您现有的应用程序有多个 ApplicationContext(例如,如果它使用 AbstractDispatcherServletInitializer),那么您可以将所有上下文源压缩到一个 SpringApplication 中。您可能遇到的主要复杂情况是,如果这不起作用并且您需要维护上下文层次结构。有关示例,请参阅有关构建层次结构的条目。包含 Web 特定功能的现有父上下文通常需要分解,以便所有 ServletContextAware 组件都在子上下文中。

    所以是的,这是可能的,但您需要将其转换为 SpringBootServletInitializer,这似乎非常相似。

    【讨论】:

    • 我尝试过,但它不起作用。我实现了一个类 WebAppInitializer extends SpringBootServletInitializer implements WebApplicationInitializer {} 但 spring-boot 不调用 onStatup 方法..