【发布时间】:2015-03-05 12:33:38
【问题描述】:
我现在对 Spring 有了一些经验,并且还使用了一些纯 java config web-apps。但是,这些通常基于安静的简单设置:
- 服务/存储库的应用程序配置
- 一个调度程序(和一些控制器)的调度程序配置
- (可选)用于保护访问的弹簧安全装置
对于我当前的项目,我需要具有不同配置的单独调度程序上下文。这不是基于 XML 的配置的问题,因为我们有一个独立于 Dispatcher 配置的专用 ContextLoaderListener。但是使用 java config 我不确定到目前为止我所做的是否还好;)
这是一个常见的 DispatcherConfig:
public class MyWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new class[]{MyAppConfig.class};
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[]{MyDispatcherConfig.class};
}
@Override
protected String[] getServletMappings() {
return new String[]{"/mymapping/*"};
}
@Override
protected String getServletName() {
return "myservlet";
}
}
如前所述,我需要带有另一个映射(和视图解析器)的第二个(第三个,...)调度程序。因此,我复制了配置并为两个 getServletName() 添加(否则两者都将被命名为“调度程序”,这将导致错误)。第二个配置是这样的:
public class AnotherWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new class[]{MyAppConfig.class};
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[]{AnotherDispatcherConfig.class};
}
@Override
protected String[] getServletMappings() {
return new String[]{"/another_mapping/*"};
}
@Override
protected String getServletName() {
return "anotherservlet";
}
}
当我这样使用它时,启动应用程序会导致 ContextLoaderListener 出现问题:
java.lang.IllegalStateException: Cannot initialize context because there is already a root application context present - check whether you have multiple ContextLoader* definitions in your web.xml!
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:277)
...
所以我从其中一个中删除了第二个 MyAppConfig.class 返回 AbstractAnnotationConfigDispatcherServletInitializer 并且工作正常。但是,这感觉不是正确的方法;)
据我了解:应该在一个 AbstractAnnotationConfigDispatcherServletInitializer 中处理所有 DispatcherConfig,还是应该像我一样将它们分开?我尝试在一个类中配置它们,但后来我的配置完全混合(所以我相信这不是理想的方式)。
您如何实施这种情况?是否可以在 AbstractAnnotationConfigDispatcherServletInitializer 之外的 java 配置中设置 ContextLoaderListener?或者我应该创建一个只有根配置的 DefaultServlet 吗?如何实现该配置的基本接口WebApplicationInitializer?
【问题讨论】:
-
您能解释一下在一个应用程序中需要多个调度程序的原因吗?前端控制器的全部意义在于您将请求多路复用到一个上。
-
@chrylis:当然。该项目更像是一个基于模块的共享服务构建工具包。它们彼此没有链接,但共享相同的基本设置和实体。在该项目中部署两个应用程序是不行的,并且尝试将调度程序配置为处理所有类型的视图技术(一些基于磁贴,其他基于 jsp,较新的在 Thymeleaf 上)也是一个坏主意。跨度>
-
为什么这是个坏主意? Spring Boot 让它变得简单。
-
Spring Boot 是另一个主题。我真的很想拥有不同的 DispatcherServlets(具有不同的 Web 上下文)。使用 web.xml 配置很容易(因为 ContextLoaderListener 没有绑定到 Dispatcher)。我确信有一个解决方案或至少是最佳实践。
-
你找到灵魂了吗?
标签: java spring spring-mvc spring-java-config