使用带有 Spring boot 的多个调度程序 servlet/Web 上下文

2022-09-01 12:57:47

我创建了一个带有父上下文(服务)和子上下文(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();
    }

}

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

  1. 将 (因此 MainApiApplication.class 配置) 移出子上下文,并且servletContainer
  2. 添加路径映射和/one/ -> ApiOne.class/two/ ApiTwo.class

弹簧靴的方法是什么?


答案 1

正如@josh-ghiloni已经说过的那样,您需要为要创建的每个孤立的Web上下文注册一个。您需要从 xml 或 java 配置类创建应用程序上下文。您可以使用和批注将共享服务添加到父上下文。下面是一个示例:ServletRegistrationBean@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;
    }
}

答案 2

创建一个声明 servlet 及其映射的。您可能还希望从调用的自动配置中排除,因为它将注册一个 at 并覆盖您的ServletRegistrationBeanDispatcherServletAutoConfigurationDispatcherServlet/

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


推荐