如何将TomcatEmbeddedServletContainerFactory与AbstractAnnotationConfigDispatcherServletInitializer一起使用
我从Spring Boot项目中找到了“TomcatEmbeddedServletContainerFactory”,它可以创建一个Tomcat嵌入式实例。 我已经有了一组“传统的”Spring(基于Java)配置类,外加一个“AbstractAnnotationConfigDispatcherServletInitializer”实现,用于设置根应用程序上下文和控制器上下文如何将TomcatEmbeddedServletContainerFactory与AbstractAnnotationConfigDispatcherServletInitializer一起使用,tomcat,spring-boot,Tomcat,Spring Boot,我从Spring Boot项目中找到了“TomcatEmbeddedServletContainerFactory”,它可以创建一个Tomcat嵌入式实例。 我已经有了一组“传统的”Spring(基于Java)配置类,外加一个“AbstractAnnotationConfigDispatcherServletInitializer”实现,用于设置根应用程序上下文和控制器上下文 public class IntegrationTestDispatcherServletInitializer ext
public class IntegrationTestDispatcherServletInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class<?>[]{ServiceModuleConfiguration.class};
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class<?>[]{WebModuleConfiguration.class };
}
}
getEmbeddedServletContainer()需要一个来自Spring boot的ServletContextInitializer,现在我不得不将它连接到我的配置类
Spring Boot的tomcat工厂是为支持这一点而建立的吗?如果是,有什么例子吗?嵌入式ServletContainerFactory确实与
嵌入式WebApplicationContext配对(不是从AbstractAnnotationConfigDispatchersServletInitializer
获得的注释ConfigWebApplicationContext
)。如果要构建WAR文件,那么鉴于初始值设定项的简单性质,最好的选择是使用SpringApplicationServletInitializer
,例如
public class IntegrationTestDispatcherServletInitializer extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(ServiceModuleConfiguration.class).child(WebModuleConfiguration.class);
}
}
如果您不想要WAR文件(如评论中所建议的,当我仔细考虑它时),只需创建一个SpringApplication
,如果它认为您正在尝试构建一个webapp(或使用上面代码中的生成器),它将使用EmbeddedServletContainerFactory
.通过更多的调试和Dave的更多输入,正确的方法是显式获取子生成器实例并调用其run()方法。这将正确启动上下文
SpringApplicationBuilder builder = new SpringApplicationBuilder();
builder.sources(ServiceModuleConfiguration.class);
childBuilder = builder.child(WebModuleConfiguration.class, WebConfiguration.class, TomcatContainerFactoryConfiguration.class);
childBuilder.run();
WebConfiguration
包含DispatcherServlet
bean
@Bean
public ServletRegistrationBean servletRegistrationBean() {
return new ServletRegistrationBean(new DispatcherServlet((WebApplicationContext) applicationContext), "/*");
}
TomcatContainerFactoryConfiguration
包含TomcatEmbeddedServletContainerFactory
bean
@Bean
public EmbeddedServletContainerFactory embeddedServletContainerFactory() {
return new TomcatEmbeddedServletContainerFactory("", 8080);
}
我没有让SpringServletContainerInitializer
启动web应用程序。我使用的是AnnotationConfigEmbeddedWebApplicationContext
和EmbeddedServletContainerFactory
的bean定义。容器本身启动,但我猜是为了实现上述IntegrationTestDispatchrServletInitializer
必须运行SpringServletContainerInitializer
吗?是的,对不起,我不知道您想做什么。如果您不想构建war文件并部署它,那么ServletContextInitializer
将不会有帮助,如果您想要嵌入式容器,您可能不想要war文件。为什么不呢st使用SpringApplication
或直接使用构建器?好的,我们将对此进行调查。我的目的是从嵌入式tomcat运行一个简单的集成测试,而不用构建WAR并部署它。SpringApplicationBuilder=new SpringApplicationBuilder(WebModuleConfiguration.class,ServiceModuleConfiguration.class);builder.contextClass(AnnotationConfigEmbeddedWebApplicationContext.class);builder.application().run()
这是启动上下文,但是它看起来并没有给我一个正常的DispatcherServlet设置。但是现在的问题是,如果我必须像使用AbstractDispatcherServletInitializer那样手动注册它,我将需要使用控制器bean访问应用程序上下文?我看不出如何使用它从构建器/应用程序中获取et?是的,我明白了。要获得一个DispatcherServlet
来拥有您的上下文,您需要创建一个该类型的@Bean
,并将其放在您的应用程序上下文中。这应该不是什么大问题吗?注意,要从原始应用程序中保留应用程序上下文层次结构,您需要使用SpringApplic就像上面的示例中一样,是AnationBuilder
(或同等产品)。也许您的原始应用不需要这种层次结构(大多数应用不需要)。
@Bean
public EmbeddedServletContainerFactory embeddedServletContainerFactory() {
return new TomcatEmbeddedServletContainerFactory("", 8080);
}