我有一个简单的@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属性可能就是这里的答案,但似乎没有效果。
答案 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。我可以解决这个问题,如果我花了一些时间来玩它,但是对于我的特定用例,在本地运行时并不重要,所以我坚持使用我的解决方案。