2

我有一个 Spring Boot 应用程序正在部署到 Tomcat 的外部实例。主类扩展 SpringBootServletInitializer 并覆盖方法configureonStartup。在方法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.onStartup(servletContext);,但随后在部署应用程序时收到一个错误,即根上下文已存在。

注册 DispatcherServlets 和覆盖 onStartup 方法的正确方法是什么?是否需要调用onStartup的超级实现?

4

1 回答 1

1

我能够通过首先调用 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/*");
    }
}
于 2020-10-16T23:06:59.453 回答