如何在扩展 SpringBootServletInitializer 时注册 DispatcherServlets 并覆盖 onStartup
How to register DispatcherServlets and override onStartup when extending SpringBootServletInitializer
我有一个 spring 启动应用程序正在部署到 Tomcat 的外部实例。主要的 class 扩展了 SpringBootServletInitializer 并覆盖了方法 configure 和 onStartup。在方法configure中,初始化了一个自定义环境,为activemq提供解密用户密码的加密器,因为jasypt是在activemq之后才初始化的。这是我从 jasypt-spring-boot 文档中得到的。
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
try {
StandardEncryptableServletEnvironment env = StandardEncryptableServletEnvironment.builder().encryptor(encryptor).build();
return application.environment(env).sources(AxleServer.class);
} catch (FileNotFoundException e) {
logger.error("Could not load encryptable environment", e);
return application.sources(AxleServer.class);
}
}
在方法onStartup中我正在配置DispatcherServlets:
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
context.register(RemotingConfig.class);
servletContext.addListener(new ContextLoaderListener(context));
ServletRegistration.Dynamic restDispatcher = servletContext.addServlet("rest-dispatcher", new DispatcherServlet(context));
restDispatcher.setLoadOnStartup(1);
restDispatcher.addMapping("/rest/*");
ServletRegistration.Dynamic remotingDispatcher = servletContext.addServlet("remoting-dispatcher", new DispatcherServlet(context));
remotingDispatcher.setLoadOnStartup(2);
remotingDispatcher.addMapping("/remoting/*");
}
问题是 configure 方法从未被调用,因为它是从 onStartup 的超级实现中调用的。我尝试调用 super 实现 super.onStartup(servletContext);
但是我收到一个错误,指出在部署应用程序时根上下文已经存在。
注册 DispatcherServlets 和覆盖 onStartup 方法的正确方法是什么?是否需要调用onStartup的super实现?
我能够通过首先调用 super.onStartup 然后从 ServletContext 属性获取根上下文来解决这个问题
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
super.onStartup(servletContext);
Object obj = servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
if(obj instanceof AnnotationConfigServletWebServerApplicationContext) {
AnnotationConfigServletWebServerApplicationContext context = (AnnotationConfigServletWebServerApplicationContext) obj;
context.register(RemotingConfig.class);
ServletRegistration.Dynamic restDispatcher = servletContext.addServlet("rest-dispatcher", new DispatcherServlet(context));
restDispatcher.setLoadOnStartup(1);
restDispatcher.addMapping("/rest/*");
ServletRegistration.Dynamic remotingDispatcher = servletContext.addServlet("remoting-dispatcher", new DispatcherServlet(context));
remotingDispatcher.setLoadOnStartup(2);
remotingDispatcher.addMapping("/remoting/*");
}
}
我有一个 spring 启动应用程序正在部署到 Tomcat 的外部实例。主要的 class 扩展了 SpringBootServletInitializer 并覆盖了方法 configure 和 onStartup。在方法configure中,初始化了一个自定义环境,为activemq提供解密用户密码的加密器,因为jasypt是在activemq之后才初始化的。这是我从 jasypt-spring-boot 文档中得到的。
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
try {
StandardEncryptableServletEnvironment env = StandardEncryptableServletEnvironment.builder().encryptor(encryptor).build();
return application.environment(env).sources(AxleServer.class);
} catch (FileNotFoundException e) {
logger.error("Could not load encryptable environment", e);
return application.sources(AxleServer.class);
}
}
在方法onStartup中我正在配置DispatcherServlets:
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
context.register(RemotingConfig.class);
servletContext.addListener(new ContextLoaderListener(context));
ServletRegistration.Dynamic restDispatcher = servletContext.addServlet("rest-dispatcher", new DispatcherServlet(context));
restDispatcher.setLoadOnStartup(1);
restDispatcher.addMapping("/rest/*");
ServletRegistration.Dynamic remotingDispatcher = servletContext.addServlet("remoting-dispatcher", new DispatcherServlet(context));
remotingDispatcher.setLoadOnStartup(2);
remotingDispatcher.addMapping("/remoting/*");
}
问题是 configure 方法从未被调用,因为它是从 onStartup 的超级实现中调用的。我尝试调用 super 实现 super.onStartup(servletContext);
但是我收到一个错误,指出在部署应用程序时根上下文已经存在。
注册 DispatcherServlets 和覆盖 onStartup 方法的正确方法是什么?是否需要调用onStartup的super实现?
我能够通过首先调用 super.onStartup 然后从 ServletContext 属性获取根上下文来解决这个问题
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
super.onStartup(servletContext);
Object obj = servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
if(obj instanceof AnnotationConfigServletWebServerApplicationContext) {
AnnotationConfigServletWebServerApplicationContext context = (AnnotationConfigServletWebServerApplicationContext) obj;
context.register(RemotingConfig.class);
ServletRegistration.Dynamic restDispatcher = servletContext.addServlet("rest-dispatcher", new DispatcherServlet(context));
restDispatcher.setLoadOnStartup(1);
restDispatcher.addMapping("/rest/*");
ServletRegistration.Dynamic remotingDispatcher = servletContext.addServlet("remoting-dispatcher", new DispatcherServlet(context));
remotingDispatcher.setLoadOnStartup(2);
remotingDispatcher.addMapping("/remoting/*");
}
}