Spring 启动多模块 servletDispatchers
Spring boot multi module servletDispatchers
我有以下项目结构
-Project
|-config
| |-modules
| |-admin
| |-web
|- platform
Platform 是包含 spring-boot start class 的项目,
平台依赖于配置,配置依赖于目录模块中的所有内容
platform也是通过mvn spring-boot:运行命令启动的模块。
我想要完成的事情是模块 admin 和 web(两个 web 应用程序)都有自己的映射,比如
- /管理员
- /网络
下面的代码表示admin模块中的一个controller,web模块也包含一个类似的controller(就是重点)
@Controller
public class AdminController {
@RequestMapping("/")
public String adminController() {
return "admin";
}
}
这里是管理模块配置的一些代码
@Configuration
public class Config implements EmbeddedServletContainerCustomizer {
@Autowired
protected WebApplicationContext webApplicationContext;
@Autowired
protected ServerProperties server;
@Autowired(required = false)
protected MultipartConfigElement multipartConfig;
protected DispatcherServlet createDispatcherServlet() {
AnnotationConfigEmbeddedWebApplicationContext webContext = new AnnotationConfigEmbeddedWebApplicationContext();
webContext.setParent(webApplicationContext);
webContext.scan("some.base.package");
return new DispatcherServlet(webContext);
}
protected ServletRegistrationBean createModuleDispatcher(DispatcherServlet apiModuleDispatcherServlet) {
ServletRegistrationBean registration =
new ServletRegistrationBean(apiModuleDispatcherServlet,
"/admin");
registration.setName("admin");
registration.setMultipartConfig(this.multipartConfig);
return registration;
}
@Bean(name = "adminsServletRegistrationBean")
public ServletRegistrationBean apiModuleADispatcherServletRegistration() {
return createModuleDispatcher(createDispatcherServlet());
}
public void customize(ConfigurableEmbeddedServletContainer container) {
container.setContextPath("/admin");
}
}
网络模块也有类似的东西
我已经尝试实现了一些给定的答案。
- Spring Boot (JAR) with multiple dispatcher servlets for different REST APIs with Spring Data REST
- 还有很多谷歌搜索
当我让组件扫描时,扫描两个模块(删除 ComponentScan 过滤器)
我得到一个发现模糊映射的异常,说两个控制器方法分派到同一路径“/”
但是当禁用其中一个模块的组件扫描时,管理模块确实会映射到 /admin。
当我禁用两个控制器时,我看到 /web 和 /admin dispatchServlets 被映射。
所以我理解异常,但我不明白如何解决这个问题。
对我来说,我必须按模块执行此操作,我不想使用
映射它
@RequestMapping("/admin")
在控制器上class
我还尝试在 application.properties
中指定 contextPath 和 servletPath
所以我的问题是:达到我的目标的最佳方法是什么,或者我是否正在尝试使用 spring-boot 来处理它不适合的东西。
编辑
概念证明会很好
您应该做的是将 AdminController 和 WebController 放在不同的包中。
some.base.admin.package
some.base.web.package
并且在相应的配置中只扫描你需要的包来注册DispatcherServlet
管理配置
webContext.scan("some.base.admin.package");
网络配置
webContext.scan("some.base.web.package");
这样在对应的WebApplicationContext
中每个DispatcherServlet
只有一个映射可用于"/"
所以我找到了解决方案。
你可以在这里看看 link
您必须在主应用程序中注册调度程序 servlet,并且不要使用 @SpringBootApplication 注释。
要查看完整示例,只需签出项目并检查代码
编辑: 本周晚些时候我会提供详细的答案
我有以下项目结构
-Project
|-config
| |-modules
| |-admin
| |-web
|- platform
Platform 是包含 spring-boot start class 的项目, 平台依赖于配置,配置依赖于目录模块中的所有内容 platform也是通过mvn spring-boot:运行命令启动的模块。
我想要完成的事情是模块 admin 和 web(两个 web 应用程序)都有自己的映射,比如
- /管理员
- /网络
下面的代码表示admin模块中的一个controller,web模块也包含一个类似的controller(就是重点)
@Controller
public class AdminController {
@RequestMapping("/")
public String adminController() {
return "admin";
}
}
这里是管理模块配置的一些代码
@Configuration
public class Config implements EmbeddedServletContainerCustomizer {
@Autowired
protected WebApplicationContext webApplicationContext;
@Autowired
protected ServerProperties server;
@Autowired(required = false)
protected MultipartConfigElement multipartConfig;
protected DispatcherServlet createDispatcherServlet() {
AnnotationConfigEmbeddedWebApplicationContext webContext = new AnnotationConfigEmbeddedWebApplicationContext();
webContext.setParent(webApplicationContext);
webContext.scan("some.base.package");
return new DispatcherServlet(webContext);
}
protected ServletRegistrationBean createModuleDispatcher(DispatcherServlet apiModuleDispatcherServlet) {
ServletRegistrationBean registration =
new ServletRegistrationBean(apiModuleDispatcherServlet,
"/admin");
registration.setName("admin");
registration.setMultipartConfig(this.multipartConfig);
return registration;
}
@Bean(name = "adminsServletRegistrationBean")
public ServletRegistrationBean apiModuleADispatcherServletRegistration() {
return createModuleDispatcher(createDispatcherServlet());
}
public void customize(ConfigurableEmbeddedServletContainer container) {
container.setContextPath("/admin");
}
}
网络模块也有类似的东西
我已经尝试实现了一些给定的答案。
- Spring Boot (JAR) with multiple dispatcher servlets for different REST APIs with Spring Data REST
- 还有很多谷歌搜索
当我让组件扫描时,扫描两个模块(删除 ComponentScan 过滤器)
我得到一个发现模糊映射的异常,说两个控制器方法分派到同一路径“/”
但是当禁用其中一个模块的组件扫描时,管理模块确实会映射到 /admin。
当我禁用两个控制器时,我看到 /web 和 /admin dispatchServlets 被映射。
所以我理解异常,但我不明白如何解决这个问题。 对我来说,我必须按模块执行此操作,我不想使用
映射它@RequestMapping("/admin")
在控制器上class
我还尝试在 application.properties
中指定 contextPath 和 servletPath所以我的问题是:达到我的目标的最佳方法是什么,或者我是否正在尝试使用 spring-boot 来处理它不适合的东西。
编辑 概念证明会很好
您应该做的是将 AdminController 和 WebController 放在不同的包中。
some.base.admin.package
some.base.web.package
并且在相应的配置中只扫描你需要的包来注册DispatcherServlet
管理配置
webContext.scan("some.base.admin.package");
网络配置
webContext.scan("some.base.web.package");
这样在对应的WebApplicationContext
中每个DispatcherServlet
只有一个映射可用于"/"
所以我找到了解决方案。 你可以在这里看看 link
您必须在主应用程序中注册调度程序 servlet,并且不要使用 @SpringBootApplication 注释。
要查看完整示例,只需签出项目并检查代码
编辑: 本周晚些时候我会提供详细的答案