SpringBoot 无法从多模块 Java 应用程序中的另一个模块识别 RestController
Posted
技术标签:
【中文标题】SpringBoot 无法从多模块 Java 应用程序中的另一个模块识别 RestController【英文标题】:SpringBoot doesn't recognize RestController from another module in multi module Java application 【发布时间】:2016-09-05 02:49:39 【问题描述】:我已经花了很长时间,但我无法解决这个(配置)问题。
技术栈: Java (1.8)、Springboot(starter-parent、starter-web)、Maven、IntelliJ IDEA
描述:尝试创建一个由(起初)2个模块组成的多模块Java应用程序:
-
core 模块:主模块(主要业务逻辑,其他所有模块都应该通过这个模块查看和交互)。该模块包含主应用程序类。
webgateway 模块:简单的 Rest 控制器,它将映射请求并调用 core 模块
问题: Springboot 未从 webgateway 模块加载/扫描 RestController => 发送 http 请求时出现 404 错误
Github 存储库:https://github.com/Sorin-J/Greeter
项目配置:
Greeter
|
+ pom.xml (parent pom)
|
+ -- core
| |
| + ...
| |
| + pom.xml
|
+ -- webgateway
|
+ ...
|
+ pom.xml (depends on core pom.xml)
父 pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.bet.jbs</groupId>
<artifactId>Greeter</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<modules>
<module>core</module>
<module>webgateway</module>
</modules>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.3.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
</project>
核心模块 pom.xml :
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>Greeter</artifactId>
<groupId>com.bet.jbs</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>core</artifactId>
</project>
webgateway 模块 pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>Greeter</artifactId>
<groupId>com.bet.jbs</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>webgateway</artifactId>
<dependencies>
<dependency>
<groupId>com.bet.jbs</groupId>
<artifactId>core</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
MainApplication 类来自 core 模块:
package com.bet.jbs.core;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan(basePackages = "com.bet.jbs.core", "com.bet.jbs.webgateway")
@EnableAutoConfiguration
public class MainApplication
public static void main(String[] args) throws Exception
SpringApplication.run(MainApplication.class, args);
GreetingController 类来自 webgateway 模块:
package com.bet.jbs.webgateway.controller;
import com.bet.jbs.core.util.GreetingGenerator;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class GreetingController
@RequestMapping(value = "/webgreeting", method = RequestMethod.GET)
public String getGreeting()
return "WEBGATEWAY module says " + GreetingGenerator.getRandomGreeting();
只是为了测试一个相同的 REST 控制器在 core 模块中是否可以正常工作,我也在 中创建了一个类似的 GreetingController 类核心 模块(这个工作正常):
package com.bet.jbs.core.controller;
import com.bet.jbs.core.util.GreetingGenerator;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
/*
* This REST controller should not be in the CORE component.
* It is just for proving that this controller is recognized and the other one from WEBGATEWAY component is not.
*
*/
@RestController
public class GreetingController
@RequestMapping(value = "/coregreeting", method = RequestMethod.GET)
public String getGreeting()
return "CORE module says " + GreetingGenerator.getRandomGreeting();
【问题讨论】:
【参考方案1】:Spring Boot 主应用在core
模块中,对webgateway
模块没有依赖。因此带有控制器的类在运行时不会出现,也不能被spring发现。
修复:将webgateway
的依赖添加到核心或将启动器/主类移动到webgateway
模块。
您还可以使用第三个模块来执行启动并依赖于 core
和 webgateway
。
【讨论】:
已经依赖于 webgateway -> 核心。添加一个反向的将抛出(注释处理不支持模块周期)。此外,核心不应依赖于特定的网关。我们可以使用另一个网关(例如 LAN TCP/IP)部署项目。我将尝试使用第三个模块的选项。 确实应该避免循环。在建议使用第三个模块来获得干净的依赖项时,我考虑到了这一点,但没有正确解释。 适用于第三个模型(依赖于核心和 webgateway)。拥有一个完整的模块只是为了启动应用程序有点奇怪(似乎有点矫枉过正),但如果没有其他优雅的方法来解决这个问题,我可以接受。感谢您的反馈。 很高兴听到它成功了。关于奇怪的感觉:我倾向于从单个模块项目开始,尤其是在使用 Spring Boot 时。如果它变得太大,我会尝试将它分成多个单独的应用程序。如果有共同的功能,你可以提取一个核心模块。 @JuanMonsalve 我也有这个问题。通过 2 个步骤修复它: 1.) maven: clean + install 在父项目上。 2.) IntelliJ => 文件 => 使缓存无效/重新启动。【参考方案2】:从前一天开始我就陷入了这个问题...下面的解决方案肯定会为您节省大量时间!
我是这样解决的:
为主Application
类创建一个单独的模块。
x-服务
pom.xml(父) child1-模块 pom.xml child2-模块 pom.xml 应用程序模块 pom.xml(包含 child1 和 child2 的依赖项) src/main/java/Application.java将所有模块作为依赖项添加到具有应用程序类的模块的pom中。
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>x-service</artifactId>
<groupId>com.a.b.c</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>app-module</artifactId>
<dependencies>
<dependency>
<groupId>com.a.b.cs</groupId>
<artifactId>child1-module</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.a.b.cs</groupId>
<artifactId>child1-module</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<executable>true</executable>
</configuration>
</plugin>
</plugins>
</build>
将主 pom 保留为父 pom。
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<packaging>pom</packaging>
<modules>
<module>child1-module</module>
<module>child2-module</module>
<module>app-module</module>
</modules>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.2.RELEASE</version>
<relativePath/>
</parent>
<groupId>com.a.b.c</groupId>
<artifactId>x-service</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>3.0.0</version>
</plugin>
</plugins>
</build>
将父 pom 工件添加为所有子 pom 中的父级。
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>dxg-service</artifactId>
<groupId>com.a.b.c</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>com.a.b.c</groupId>
<artifactId>child1-module</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>com.a.b.c</groupId>
<artifactId>child2-modulde</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
更多细节在这里: https://medium.com/macoclock/how-create-multi-module-project-in-intellij-on-macos-50f07e52b7f9
【讨论】:
【参考方案3】:我添加了正确的依赖项,但 Spring Boot 仍然没有找到我的新控制器。似乎 IntelliJ IDEA (2020.3.2) 或 Maven (3.3.6) 在添加模块时无法正确更新。这为我解决了这个问题:
马文: 清理 + 安装在父项目上
在 IntelliJ 中的文件菜单 Invalidate Caches / Restart..
【讨论】:
【参考方案4】:如前所述,您应该在其中拥有带有 setup spring web starter 的父 pom,并且其他模块必须将该父 pom 作为其父级。小心将你的根 pom 项目添加到 maven。在 IDE 中打开 maven 并添加 pom。
【讨论】:
以上是关于SpringBoot 无法从多模块 Java 应用程序中的另一个模块识别 RestController的主要内容,如果未能解决你的问题,请参考以下文章