Подтвердить что ты не робот

Использование нескольких сервлетов диспетчера/веб-контекстов с загрузкой spring

Я создал приложение загрузки spring с родительским контекстом (службами) и дочерним контекстом (spring -webmvc-контроллеры):

@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. Я думаю, что я должен сделать две вещи:

  • Переместите servletContainer (таким образом, конфигурацию MainApiApplication.class) из дочернего контекста и
  • добавить отображение пути /one/ → ApiOne.class и /two/ApiTwo.class

Каков способ загрузки spring для этого?

4b9b3361

Ответ 1

Как уже сказал @josh-ghiloni, вам нужно зарегистрировать ServletRegistrationBean для каждого изолированного веб-контекста, который вы хотите создать. Вам нужно создать контекст приложения из класса конфигурации 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;
    }
}

Ответ 2

Создайте ServletRegistrationBean, который объявит сервлет и его сопоставления. Вероятно, вы также захотите исключить DispatcherServletAutoConfiguration из вызванных автоконфигураций, потому что он зарегистрирует DispatcherServlet at / и переопределит ваш

EDIT Несмотря на мой комментарий ниже, говорящий, что вам может не понадобиться это, если вам не нужны ваши API-интерфейсы, запущенные на отдельных портах (и это не похоже на вас), Дэйв Сиер, один из авторов из Spring Boot, ответил на очень похожий вопрос: Настроить несколько сервлетконтейнеров/сервлетов с загрузкой Spring