java - 在初始化 SpringBootApplication 的 ApplicationContextInitializer bean 之前启动一个 @WebServlet

标签 java spring tomcat servlets spring-boot

我有一个简单的@WebServlet 定义如下,其目的是构造几个静态 ApplicationContextInitializer beans,然后在我的 Spring Boot 应用程序中需要它们(为了记录,我正在实现 ServletContextListener 因为我还需要添加一些ServletContext 的属性)。

@WebServlet(urlPatterns = {"/blah"}, loadOnStartup = -1000)
public class MyServlet implements ServletContextListener {

    @Override
    public void contextInitialized(ServletContextEvent sce) {
        AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext(MyConfiguration.class);
        Application.logitContextInitializer = context.getBean(LogitContextInitializer.class);
        Application.configWsClientInitializer = context.getBean(ConfigWsClientInitializer.class);
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
    }

}

我的 Spring Boot 应用程序如下所示:

@SpringBootApplication
public class Application extends SpringBootServletInitializer {

    public static LogitContextInitializer logitContextInitializer;
    public static ConfigWsClientInitializer configWsClientInitializer;

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder in) {
        in.application().addInitializers(logitContextInitializer, configWsClientInitializer);

        SpringApplicationBuilder applicationBuilder = in.sources(Application.class);
        return applicationBuilder;
    }

}

但是,在运行我的应用程序时,要么部署到专用的 Tomcat 服务器,要么以编程方式触发,例如:

    new Application().configure(
            new SpringApplicationBuilder(MyServlet.class, Application.class)).run(args);

我找不到一种方法来触发 MyServlet 在 ApplicationContextInitializer bean 初始化之前启动。我认为我的 @WebServlet 中的 loadOnStartup 属性可能是这里的答案,但它似乎没有任何效果。

最佳答案

我设法通过覆盖 SpringBootServletInitializer 的 onStartup 方法部分解决了这个问题,例如:

@SpringBootApplication
public class Application extends SpringBootServletInitializer {

    private final StartupHandler startupHandler = new StartupHandler();

    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
        startupHandler.handle(servletContext);
        super.onStartup(servletContext);
    }

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder in) {
        startupHandler.addInitializersToApplication(in);
        return in.sources(Application.class);
    }

StartupHandler 是一个新类,负责在 handle 方法中创建我的初始化程序 bean 并在 ServletContext 上设置属性。 addInitializersToApplication 方法负责使用这些初始化程序 bean。

唯一不起作用的情况是当我在本地运行时 (mvn spring-boot:run...) 而不是部署到专用的 Tomcat - 在前一种情况下,我的主要方法从不调用 onStartup。如果我花更多时间尝试解决这个问题,我可能会解决这个问题,但是对于我的特定用例来说,在本地运行时它并不重要,所以我坚持使用现有的解决方案。

关于java - 在初始化 SpringBootApplication 的 ApplicationContextInitializer bean 之前启动一个 @WebServlet,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39169137/

相关文章:

tomcat - 用于 liferay/tomcat 的 Bluemix buildpack : failed to accept connections within health check timeout

Java NIO.2 CompletetionHandler 未到达

java - 优化原生 Android 代码 - 编译器标志

java - 为什么使用toString方法后仍然得到[]?

java - 无法使用 Google App Engine (GAE) 运行 Spring Data Rest

java - 如何在 Spring WebClient 中捕获 ConnectionException?

java - 删除 CSV 中的空白行

spring - 使用 gzip 压缩 rest 响应

eclipse - 无法在eclipse中将tomcat作为外部工具启动

eclipse - 导入tomcat没有 'server'选项