В моей настройке мне нужно выполнить развертывание на основе отдельного веб-контекста tomcat (и я читаю имена контекстов из файла конфигурации, поэтому я удалил КОРНЕВОЙ контекст по умолчанию). Я настроил Tomcat с помощью tomcatFactory Bean и AnnotationConfigWebApplicationContext для сканирования моих RESTконтроллеров (который работает).
Однако я заметил две аномалии при этом подходе:
- Хотя мой экземпляр WebMvcConfigurer создан (я зарегистрировал конструктор), функция addInterceptors не выполняется.
- Мои Beans инициализируются дважды, например. У меня есть этот собственный компонент DataSource, экземпляр которого создается дважды. Скорее всего, это связано с сканированием отдельно Spring ApplicationContext и AnnotationConfigWebApplicationContext (просто догадываюсь, потому что он создается только дважды, даже когда я добавляю 3 контекста), но в AnnotationConfigWebApplicationContext я уже явно отключил сканирование пространства имен источника данных, а также даже просто пытался вызовите setParent в мой AnnotationConfigWebApplicationContext, но это не помогает: appContext.setParent(applicationContext);. При доступе к компоненту из моих контроллеров REST используется только первый из них.
@SpringBootApplication(exclude = ServletWebServerFactoryAutoConfiguration.class)
@ComponentScan({"mynamespace"})
@EnableAutoConfiguration(exclude = {QuartzAutoConfiguration.class, WebMvcAutoConfiguration.class})
public class MySpringBootContainer {
private static final Logger log = LoggerFactory.getLogger(MySpringBootContainer.class);
public static void main(String[] args) {
SpringApplication app = new SpringApplication(SpringBootContainer.class);
app.setDefaultProperties(Map.of(
"spring.config.import", "file:./config.yml")
);
app.run(args);
}
@Bean
public TomcatServletWebServerFactory tomcatFactory() {
TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory() {
@Override
protected TomcatWebServer getTomcatWebServer(Tomcat tomcat) {
Context webContext = tomcat.addContext("/test1", null);
Context webContext2 = tomcat.addContext("/test2", null);
AnnotationConfigWebApplicationContext appContext = new AnnotationConfigWebApplicationContext();
appContext.setServletContext(webC ontext.getServletContext());
appContext.scan("mynamespace");
appContext.refresh();
tomcat.getHost().removeChild(tomcat.getHost().findChild("")); // remove default app context
var dispatcherServlet = new DispatcherServlet(appContext);
Tomcat.addServlet(webContext, "default", dispatcherServlet);
webContext.addServletMappingDecoded("/*", "default");
appContext.setServletContext(webContext2.getServletContext()); // is this necessary
var dispatcherServlet2 = new DispatcherServlet(appContext);
Tomcat.addServlet(webContext2, "default", dispatcherServlet2);
webContext2.addServletMappingDecoded("/*", "default");
return super.getTomcatWebServer(tomcat);
}
});
return factory;
}
}
Подробнее здесь: https://stackoverflow.com/questions/791 ... springboot