详尽的Spring Boot多模块开发与排坑指南 - Go语言中文社区

详尽的Spring Boot多模块开发与排坑指南


创建项目

创建一个 SpringBoot 项目非常的简单,简单到这里根本不用再提。你可以在使用 IDEA 新建项目时直接选择 Spring Initlalize 创建一个 Spring Boot 项目,也可以使用 Spring 官方提供的 Spring Boot 项目生成页面得到一个项目。

下面介绍一下使用 Spring 官方生成的方式,如果你已经有了一个 Spring Boot 项目,这部分可以直接跳过。

1.  打开 https://start.spring.io/ 

2.  填写 group 和 Artifact 信息,选择依赖(我选择了 Spring Web 和 Lombok )。 

spring 官网创建初始项目

3.  点击 Generate 按钮下载项目。

4.  打开下载的项目,删除无用的 .mvn 文件夹,mvnw 、 mvnw.cmd 、HELP.md 文件。

到这里已经得到了一个 Spring Boot 初始项目了,我们直接导入到 IDEA 中,看一眼 pom.xml 的内容。

  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  3.     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">  
  4.     <modelVersion>4.0.0</modelVersion>  
  5.     <parent>  
  6.         <groupId>org.springframework.boot</groupId>  
  7.         <artifactId>spring-boot-starter-parent</artifactId>  
  8.         <version>2.2.5.RELEASE</version>  
  9.         <relativePath/> <!-- lookup parent from repository -->  
  10.     </parent>  
  11.     <groupId>com.wdbyte</groupId>  
  12.     <artifactId>springboot-module-demo</artifactId>  
  13.     <version>0.0.1-SNAPSHOT</version>  
  14.     <name>springboot-module-demo</name>  
  15.     <description>Demo project for Spring Boot</description>  
  16.     <properties>  
  17.         <java.version>1.8</java.version>  
  18.     </properties> 
  19.     <dependencies>  
  20.         <dependency>  
  21.             <groupId>org.springframework.boot</groupId>  
  22.             <artifactId>spring-boot-starter-web</artifactId>  
  23.         </dependency>  
  24.         <dependency>  
  25.             <groupId>org.projectlombok</groupId>  
  26.             <artifactId>lombok</artifactId>  
  27.             <optional>true</optional>  
  28.         </dependency>  
  29.         <dependency>  
  30.             <groupId>org.springframework.boot</groupId>  
  31.             <artifactId>spring-boot-starter-test</artifactId>  
  32.             <scope>test</scope>  
  33.             <exclusions>  
  34.                 <exclusion>  
  35.                     <groupId>org.junit.vintage</groupId>  
  36.                     <artifactId>junit-vintage-engine</artifactId>  
  37.                 </exclusion>  
  38.             </exclusions>  
  39.         </dependency>  
  40.     </dependencies>  
  41.     <build>  
  42.         <plugins>  
  43.             <plugin>  
  44.                 <groupId>org.springframework.boot</groupId>  
  45.                 <artifactId>spring-boot-maven-plugin</artifactId>  
  46.             </plugin>  
  47.         </plugins>  
  48.     </build>  
  49. </project> 

把目录结构调整成自己想要的结构,然后添加 controller 和 entity 用于测试。

项目目录结构

ProductController 类源代码。

  1. @RestController  
  2. @RequestMapping("/product")  
  3. public class ProductController {  
  4.     /**  
  5.      * 获取商品列表  
  6.      *  
  7.      * @return  
  8.      */  
  9.     @GetMapping("/list")  
  10.     public Map list() {  
  11.         // 模拟查询商品逻辑  
  12.         Product product = new Product();  
  13.         product.setProductName("小米粥");  
  14.         product.setProductPrice(new BigDecimal(2.0));  
  15.         product.setProductStock(100);  
  16.         Map<String, Object> resultMap = new HashMap<>();  
  17.         resultMap.put("code", 000);  
  18.         resultMap.put("message", "成功");  
  19.         resultMap.put("data", Arrays.asList(product));  
  20.         return resultMap;  
  21.     }  

Product 类源代码。

  1. @Data  
  2. public class Product {  
  3.     /** 商品名称. */  
  4.     private String productName;  
  5.     /** 商品价格. */  
  6.     private BigDecimal productPrice;  
  7.     /** 商品库存。*/  
  8.     private int productStock;  

模块化

借助 IDEA 工具可以快速的把项目改造成 maven 多模块,这里我们把准备测试 demo 拆分为 common 和 web 两个模块,common 模块存放实体类。web 模块存放 controller 层(这里项目虽小,拆分只是为了演示)。话不多说,直接开始。

1.    配置主 pom.xml 打包方式 为 pom 

  1. <?xml version="1.0" encoding="UTF-8"?>  
  2.    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  3.             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">  
  4.        <modelVersion>4.0.0</modelVersion>  
  5.        <!-- 配置主 pom 打包方式为 pom -->  
  6.        <packaging>pom</packaging>  
  7.        ....  
  8.        .... 

2.  创建 common 模块

项目直接 new -> module。 

创建模块

选择 maven -> next,填写模块名称。 

填写模块名称

继续 next 完成模块创建。

3.  创建 web 模块

  web 模块的创建和 common 模块如出一辙,不再赘述。完成两个模块的创建之后,你会发现你的主 pom.xml 文件里自动添加了 module 部分。 

  1. <modules>  
  2.         <module>product-common</module>  
  3.         <module>product-web</module>  
  4.     </modules> 

4.  移动代码到指定模块

移动 Product.java 到 product-common 模块,其他部分代码和 resource 部分直接移动到 product-web 模块,移动完后你的代码结构是这个样子。 

多模块目录结构

到这里,多模块已经拆分完成了, 但是 ProductController  代码里的红色警告让你发现事情还没有结束。

依赖管理

处理依赖问题

你发现了代码里的红色警告,不过你也瞬间想到了是因为把 Product  类移动到了 product-common 模块,导致这里引用不到了。

红色警告

然后你查看了下 product-common 模块的 pom.xml 里的内容。

  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <project xmlns="http://maven.apache.org/POM/4.0.0"  
  3.          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  4.          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">  
  5.     <parent>  
  6.         <artifactId>springboot-module-demo</artifactId>  
  7.         <groupId>com.wdbyte</groupId>  
  8.         <version>0.0.1-SNAPSHOT</version>  
  9.     </parent>  
  10.     <modelVersion>4.0.0</modelVersion>  
  11.     <artifactId>product-common</artifactId>  
  12. </project> 

机智的在 Product-web 模块的 pom.xml 里引入 product-common,手起键落,轻松搞定。

  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <project xmlns="http://maven.apache.org/POM/4.0.0"  
  3.          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  4.          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">  
  5.     <parent>  
  6.         <artifactId>springboot-module-demo</artifactId>  
  7.         <groupId>com.wdbyte</groupId>  
  8.         <version>0.0.1-SNAPSHOT</version>  
  9.     </parent>  
  10.     <modelVersion>4.0.0</modelVersion>  
  11.     <artifactId>product-web</artifactId>  
  12.     <dependencies>  
  13.         <dependency>  
  14.             <groupId>com.wdbyte</groupId>  
  15.             <artifactId>product-common</artifactId>  
  16.         </dependency>  
  17.     </dependencies>  
  18. </project> 

满心欢喜的你快速的点击 Build->  Build Project,得到的 Error 警告刺痛了顶着黑眼圈的你。

不过你还是迅速定位了问题,查看 maven 依赖,你发现是因为没有指定 product-common 依赖的版本号。

报错信息

原来如此,因为没有指定版本号,我们指定上不就完事了嘛。在最外层的主 pom.xml 中添加 <dependencyManagement> 添加上指定依赖和要指定的版本号。 

  1. <dependencyManagement>  
  2.        <dependencies>  
  3.            <dependency>  
  4.                <groupId>com.wdbyte</groupId>  
  5.                <artifactId>product-common</artifactId>  
  6.                <version>0.0.1-SNAPSHOT</version><!-- maven 打包默认 0.0.1-SNAPSHOT 版本 -->  
  7.            </dependency>  
  8.        </dependencies>  
  9.    </dependencyManagement> 

刷新 maven ,发现项目已经不报错了,编译成功,运行启动类,熟悉的 Spring logo 又出现在眼前。

优化依赖

是的,Spring Boot 应用在改造成多模块后成功运行了起来,但是你貌似发现一个问题,模块 common 和模块 web 都继承了主 pom ,主 pom 中有 Lombok 、Spring Boot Web 和  Spring Boot Test 依赖,而 common 模块里只用到了 Lombok 啊,却一样继承了 Spring Boot 其他依赖,看来还是要改造一把。

1.  只有 common 模块用到的依赖移动到 common 模块。 

  1. <?xml version="1.0" encoding="UTF-8"?>  
  2.    <project xmlns="http://maven.apache.org/POM/4.0.0"  
  3.             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  4.             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">  
  5.        <parent>  
  6.            <artifactId>springboot-module-demo</artifactId>  
  7.            <groupId>com.wdbyte</groupId>  
  8.            <version>0.0.1-SNAPSHOT</version>  
  9.        </parent>  
  10.        <modelVersion>4.0.0</modelVersion>  
  11.        <artifactId>product-common</artifactId>  
  12.        <dependencies>  
  13.            <dependency>  
  14.                <groupId>org.projectlombok</groupId>  
  15.                <artifactId>lombok</artifactId>  
  16.                <optional>true</optional>  
  17.            </dependency>  
  18.        </dependencies>  
  19.    </project> 

2.  只有 web 模块用到的依赖移动到 web 模块。 

  1. <?xml version="1.0" encoding="UTF-8"?>  
  2.    <project xmlns="http://maven.apache.org/POM/4.0.0"  
  3.             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  4.             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">  
  5.        <parent>  
  6.            <artifactId>springboot-module-demo</artifactId>  
  7.            <groupId>com.wdbyte</groupId> 
  8.             <version>0.0.1-SNAPSHOT</version>  
  9.        </parent>  
  10.        <modelVersion>4.0.0</modelVersion>  
  11.        <artifactId>product-web</artifactId>     
  12.        <dependencies>  
  13.            <dependency>  
  14.                <groupId>com.wdbyte</groupId>  
  15.                <artifactId>product-common</artifactId>  
  16.            </dependency>  
  17.            <dependency>  
  18.                <groupId>org.springframework.boot</groupId>  
  19.                <artifactId>spring-boot-starter-web</artifactId>  
  20.            </dependency>  
  21.            <dependency>  
  22.                <groupId>org.springframework.boot</groupId>  
  23.                <artifactId>spring-boot-starter-test</artifactId>  
  24.                <scope>test</scope>  
  25.                <exclusions>  
  26.                    <exclusion>  
  27.                        <groupId>org.junit.vintage</groupId>  
  28.                        <artifactId>junit-vintage-engine</artifactId>  
  29.                    </exclusion>  
  30.                </exclusions>  
  31.            </dependency>  
  32.        </dependencies>  
  33.    </project> 

3.  抽取用到的版本号到 <properties>,这里抽取 common 模块的依赖版本。

  到这里最外层主 pom 的内容是这样的。 

  1. <?xml version="1.0" encoding="UTF-8"?>  
  2.     <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  3.              xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">  
  4.         <modelVersion>4.0.0</modelVersion>  
  5.         <packaging>pom</packaging>  
  6.         <modules>  
  7.             <module>product-common</module>  
  8.             <module>product-web</module>  
  9.         </modules>  
  10.         <parent>  
  11.             <groupId>org.springframework.boot</groupId> 
  12.              <artifactId>spring-boot-starter-parent</artifactId>  
  13.             <version>2.2.5.RELEASE</version>  
  14.             <relativePath/> <!-- lookup parent from repository -->  
  15.         </parent>  
  16.         <groupId>com.wdbyte</groupId>  
  17.         <artifactId>springboot-module-demo</artifactId>  
  18.         <version>0.0.1-SNAPSHOT</version>  
  19.         <name>springboot-module-demo</name>  
  20.         <description>Demo project for Spring Boot</description>  
  21.         <properties>  
  22.             <java.version>1.8</java.version>  
  23.             <product-common.version>0.0.1-SNAPSHOT</product-common.version>  
  24.         </properties> 
  25.         <dependencyManagement>  
  26.             <dependencies>  
  27.                 <dependency>  
  28.                     <groupId>com.wdbyte</groupId>  
  29.                     <artifactId>product-common</artifactId>  
  30.                     <version>${product-common.version}</version>  
  31.                 </dependency>  
  32.             </dependencies> 
  33.          </dependencyManagement>  
  34.         <build>  
  35.             <plugins>  
  36.                 <plugin>  
  37.                     <groupId>org.springframework.boot</groupId>  
  38.                     <artifactId>spring-boot-maven-plugin</artifactId>  
  39.                 </plugin>  
  40.             </plugins>  
  41.         </build>  
  42.     </project> 

看似完美,重新  Build->  Build Project ,发现一切正常,运行发现一切正常,访问正常。

访问接口

打包编译

好了,终于到了最后一步了,你感觉到胜利的曙光已经照到了头顶,反射出耀眼的光芒。接着就是 mvn package。

  1. [INFO] springboot-module-demo ............................. SUCCESS [  2.653 s]  
  2. [INFO] product-common ..................................... FAILURE [  2.718 s] 
  3.  [INFO] product-web ........................................ SKIPPED  
  4. [INFO] ------------------------------------------------------------------------  
  5. [INFO] BUILD FAILURE  
  6. [INFO] ------------------------------------------------------------------------  
  7. [INFO] Total time: 6.084 s  
  8. [INFO] Finished at: 2020-03-19T08:15:52+08:00  
  9. [INFO] Final Memory: 22M/87M  
  10. [INFO] ------------------------------------------------------------------------  
  11. [ERROR] Failed to execute goal org.springframework.boot:spring-boot-maven-plugin:2.2.5.RELEASE:repackage (repackage) on project product-common: Execution repackage of goal org.springframework.boot:spring-boot-m 
  12. aven-plugin:2.2.5.RELEASE:repackage failed: Unable to find main class -> [Help 1]  
  13. [ERROR] 

ERROR 让你伤心了,但是你还是从报错中寻找到了一些蛛丝马迹,你看到是  spring-boot-maven-plugin 报出的错误。重新审视你的主 pom 发现 <build> 编译插件用到了 spring-boot-maven-plugin。 

  1. <build>  
  2.         <plugins>  
  3.             <plugin>  
  4.                 <groupId>org.springframework.boot</groupId>  
  5.                 <artifactId>spring-boot-maven-plugin</artifactId>  
  6.             </plugin>  
  7.         </plugins>  
  8.     </build> 

略加思索后将这段移动到 web 模块的 pom,因为这是 Spring Boot 的打包方式,现在放在主 pom 中所有的模块都会继承到,那么对于 common 模块来说是肯定不需要的。

移动后重新打包,不管你是运行命令 mvn package 还是双击 IDEA 中的 maven 管理中的 package ,想必这时候你都已经打包成功了

IDEA 打包

在 web 模块下的目录 target 里也可以看到打包后的 jar 文件 product-web-0.0.1-SNAPSHOT.jar。可以使用 java 命令直接运行。

  1. $ springboot-module-demoproduct-webtarget>java -jar product-web-0.0.1-SNAPSHOT.jar  
  2.   .   ____          _            __ _ _  
  3.  /\ / ___'_ __ _ _(_)_ __  __ _      
  4. ( ( )___ | '_ | '_| | '_ / _` |      
  5.  \/  ___)| |_)| | | | | || (_| |  ) ) ) )  
  6.   '  |____| .__|_| |_|_| |___, | / / / /  
  7.  =========|_|==============|___/=/_/_/_/  
  8.  :: Spring Boot ::        (v2.2.5.RELEASE)  
  9. 2020-03-19 08:33:03.337  INFO 15324 --- [           main] com.wdbyte.Application                   : Starting Application v0.0.1-SNAPSHOT on DESKTOP-8SCFV4M with PID 15324 (C:Users83981Desktopspringboot-mod 
版权声明:本文来源51CTO,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:http://developer.51cto.com/art/202003/613095.htm
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2021-05-16 20:07:39
  • 阅读 ( 1262 )
  • 分类:

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢