我有一个简单的@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/