弹簧启动多模块服务托盘

2022-09-04 04:34:12

我有以下项目结构

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

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

我试图完成的是,模块管理员和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模块

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

  1. 使用带有 Spring boot 的多个调度程序 servlet/Web 上下文
  2. 具有多个调度程序 servlet 的 Spring Boot (JAR),用于具有不同 REST API 的 Spring Data REST
  3. 还有很多谷歌搜索

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

我得到一个不明确的映射发现异常,说两个控制器方法调度到同一路径“/”

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

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

所以我理解这个例外,但我不知道如何解决这个问题。对我来说,我必须为每个模块执行此操作,我不想使用

@RequestMapping("/admin")

在控制器类上

我还尝试在应用程序中指定 contextPath 和 ServletPath.properties

所以我的问题是:实现我的目标的最佳方法是什么,或者我是否试图将Spring-boot用于它不适合的事情。

编辑概念验证会很好


答案 1

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

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

有关完整示例,只需签出项目并检查代码

编辑:本周晚些时候病态提供详细的答案


答案 2

你应该做的是把你的管理员控制器和WebController放在单独的包中。

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

在相应的配置中,仅扫描您所需的软件包以注册调度程序Servlet

管理员配置

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

网络配置

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

这样在对应的每个映射中只有一个映射将可用于WebApplicationContextDispatcherServlet"/"


推荐