在SpringBootApplication的ApplicationContextInitializer bean初始化之前启动@WebServlet

时间:2016-08-26 14:52:37

标签: java spring tomcat servlets spring-boot

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

@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;
    }

}

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

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

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

select id, name, (select count(*) from table t2 where t2.parentid = t1.id) as count
from table t1

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

1 个答案:

答案 0 :(得分:0)

我设法通过覆盖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 - 在前一种情况下,我的main方法从不调用onStartup。我可以解决这个问题,如果我花了一些时间来玩它,但是对于我的特定用例,在本地运行时并不重要,所以我坚持使用我的解决方案。