Java 在 Spring Boot 中使用多个调度程序 servlet/web 上下文

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29096511/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 07:21:46  来源:igfitidea点击:

Using multiple dispatcher servlets / web contexts with spring boot

javaspringspring-mvcservletsspring-boot

提问by Jan

I created a spring boot application with a parent context (services) and child context (spring-webmvc controllers):

我创建了一个带有父上下文(服务)和子上下文(spring-webmvc 控制器)的 Spring Boot 应用程序:

@Configuration
public class MainApiApplication {

    public static void main(String[] args) {
        new SpringApplicationBuilder()
                .parent(Services.class)
                .child(ApiOne.class, MainApiApplication.class)
                .run(args);
    }

    @Bean
    public EmbeddedServletContainerFactory servletContainer() {
        return new TomcatEmbeddedServletContainerFactory();
    }

}

Now I want to add another client context (and DispatcherServlet) for my ApiTwo.class configuration. I think I have to do two things:

现在我想为我的 ApiTwo.class 配置添加另一个客户端上下文(和 DispatcherServlet)。我想我必须做两件事:

  1. Move the servletContainer (thus the MainApiApplication.class configuration) out of the child context and
  2. add a path mapping /one/ -> ApiOne.class and /two/ ApiTwo.class
  1. 将 servletContainer(即 MainApiApplication.class 配置)移出子上下文并
  2. 添加路径映射 /one/ -> ApiOne.class 和 /two/ ApiTwo.class

What is the spring boot way to do it?

spring boot 的方法是什么?

采纳答案by Kamill Sokol

As @josh-ghiloni already said, you need to register a ServletRegistrationBeanfor every isolated web context you want to create. You need to create an application context from a xml or java config class. You can use @Importand @ComponentScanannotation to add shared services to the parent context. Here is an example:

正如@josh-ghiloni 已经说过的,您需要为ServletRegistrationBean要创建的每个独立的 Web 上下文注册一个。您需要从 xml 或 java 配置类创建应用程序上下文。您可以使用@Import@ComponentScan注释将共享服务添加到父上下文。下面是一个例子:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.context.embedded.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.context.support.XmlWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;


//@ComponentScan({"..."})
//@Import({})
public class Starter {

    public static void main(String[] args) throws Exception {
        SpringApplication.run(Starter.class, args);
    }

    @Bean
    public ServletRegistrationBean apiV1() {
        DispatcherServlet dispatcherServlet = new DispatcherServlet();

        XmlWebApplicationContext applicationContext = new XmlWebApplicationContext();
        applicationContext.setConfigLocation("classpath:/META-INF/spring/webmvc-context.xml");
        dispatcherServlet.setApplicationContext(applicationContext);

        ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(dispatcherServlet, "/api/1/*");
        servletRegistrationBean.setName("api-v1");

        return servletRegistrationBean;
    }

    @Bean
    public ServletRegistrationBean apiV2() {
        DispatcherServlet dispatcherServlet = new DispatcherServlet();

        AnnotationConfigWebApplicationContext applicationContext = new AnnotationConfigWebApplicationContext();
        applicationContext.register(ResourceConfig.class);
        dispatcherServlet.setApplicationContext(applicationContext);

        ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(dispatcherServlet, "/api/2/*");
        servletRegistrationBean.setName("api-v2");
        return servletRegistrationBean;
    }
}

回答by Josh Ghiloni

Create a ServletRegistrationBeanthat declares the servlet and its mappings. You will probably also want to exclude DispatcherServletAutoConfigurationfrom the autoconfigurations called, because it will register a DispatcherServletat /and override yours

创建一个ServletRegistrationBean声明 servlet 及其映射的文件。您可能还想DispatcherServletAutoConfiguration从调用的自动配置中排除,因为它会注册一个DispatcherServletat/并覆盖您的

EDITDespite my comment below saying you might not need this, unless you need your APIs running on separate ports (and it doesn't sound like you do), Dave Syer, one of the authors of Spring Boot, answered a very similar question here: Configure multiple servletcontainers/servlets with spring boot

编辑尽管我在下面的评论说你可能不需要这个,除非你需要你的 API 在不同的端口上运行(这听起来不像你做的),Spring Boot 的作者之一 Dave Syer 在这里回答了一个非常相似的问题:配置多个servletcontainers/servlets with spring boot