Spring Boot 多模块 servletDispatchers

Posted

技术标签:

【中文标题】Spring Boot 多模块 servletDispatchers【英文标题】:Spring boot multi module servletDispatchers 【发布时间】:2015-07-30 13:09:18 【问题描述】:

我有以下项目结构

-Project
 |-config
 |  |-modules
 |     |-admin
 |     |-web
 |- platform 

Platform是包含spring-boot启动类的项目, Platform 依赖于 config 并且 config 依赖于目录 modules 中的所有内容 Platform 也是使用 mvn spring-boot:run 命令启动的模块。

我想要完成的事情是模块 admin 和 web(都是 web 应用程序)有自己的映射,比如

/管理员 /网络

以下代码表示管理模块中的一个控制器,web模块也包含一个类似的控制器(重点)

@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");


web 模块也有类似的东西

我已经尝试实施一些给定的答案。

    Using multiple dispatcher servlets / web contexts with spring boot Spring Boot (JAR) with multiple dispatcher servlets for different REST APIs with Spring Data REST 还有很多谷歌搜索

当我让组件扫描时,扫描两个模块(移除 ComponentScan 过滤器)

我得到一个 Ambiguous mapping found 异常,说两个控制器方法分派到同一个路径“/”

但是当在其中一个模块上禁用组件扫描时,管理模块确实会映射到 /admin。

当我禁用两个控制器时,我看到 /web 和 /admin dispatchServlets 被映射。

所以我理解异常,但我不明白如何解决这个问题。 对我来说,我必须每个模块都可以做到这一点,我不想使用它来映射它

@RequestMapping("/admin")

在控制器类上

我也尝试在 application.properties 中指定 contextPath 和 servletPath

所以我的问题是:达到我的目标的最佳方法是什么,或者我是否试图将 spring-boot 用于它不适合的东西。

编辑 概念证明会很好

【问题讨论】:

【参考方案1】:

所以我找到了解决方案。 你可以看看这里link

您必须在主应用程序中注册调度程序 servlet,并且不要使用 @SpringBootApplication 注解。

对于一个完整的例子,只需签出项目并检查代码

编辑:本周晚些时候将提供详细答案

【讨论】:

【参考方案2】:

你应该做的是将你的 AdminController 和 WebController 放在不同的包中。

some.base.admin.package
some.base.web.package 

并且在相应的配置中只扫描你需要的包来注册 DispatcherServlet

管理配置

webContext.scan("some.base.admin.package");

网页配置

webContext.scan("some.base.web.package");

这样在每个DispatcherServlet对应的WebApplicationContext中,"/"只有一个映射可用

【讨论】:

我将它们放在单独的包中,甚至是单独的模块中。并且扫描方法对我也不起作用。

以上是关于Spring Boot 多模块 servletDispatchers的主要内容,如果未能解决你的问题,请参考以下文章

多模块 Gradle 项目 - 从 Spring-Boot 1.5 迁移到 2.1

配置 Spring Boot 多模块项目的问题

Spring Boot - 多模块多环境配置,大厂必备技能

多模块 Spring Boot 项目中的 Gradle 依赖插件

Spring Boot 多模块 servletDispatchers

Spring-Boot构建多模块项目