大厂Java项目如何进行Maven多模块管理

什么是多模块管理

多模块管理简单地理解就是一个 Java 工程项目中不止有一个 pom.xml 文件,会在不一样的目录中有多个这样的文件,进而实现 Maven 的多模块管理java

为何要使用多模块管理

随着业务的增加,代码会出现如下问题:git

  • 不一样业务之间的代码互相耦合,难以区分且快速定位问题
  • 增长开发成本,入手难度增高
  • 开发界线模糊,不易定位到具体负责人
  • 对于有特殊需求的模块没法拆解,好比:上传 maven 仓库只须要部分代码便可,但因为只有 1 个模块,不得不所有上传

故而拆分模块以后,能够避免上述问题github

模块拆分方案

一般拆分有 2 种方案web

按照结构拆分spring

- project
  - project-service
  - project-controller
  - project-dao
复制代码

按照业务拆分apache

- project
  - project-order
  - project-account
  - project-pay
复制代码

实际项目结构

以一个普通 Spring Boot 项目为例,首先放一张图,看一下总体项目完成后的结构bash

其中目录结构为app

- detail-page
  - detail-client
  - detail-service
  - detail-start
复制代码
  • detail-client 用于放须要打包传到 maven 库的代码
  • detail-service 用于放置主要的业务逻辑代码
  • detail-start 用于放启动代码

其中须要注意的是 pom.xml 的文件的配置,该配置决定了父子模块之间的关系maven

一、detail-page 的 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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.6.RELEASE</version>
    </parent>
 <modelVersion>4.0.0</modelVersion> <groupId>com.drawcode</groupId> <artifactId>detail-page</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>pom</packaging> <!-- 此处必须为pom --> <name>detail-page</name>  <properties> <java.version>1.8</java.version> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> </properties>  <!-- modules即为父子关系 --> <modules> <module>detail-client</module> <module>detail-service</module> <module>detail-start</module> </modules>  <!-- dependencyManagement很是重要,决定了子pom.xml是否能够直接引用父pom.xml的包 --> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> <version>2.2.6.RELEASE</version> </dependency>  <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>2.2.6.RELEASE</version> </dependency>  <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency>  <!--注意这个包就是项目自己的模块--> <dependency> <groupId>com.drawcode</groupId> <artifactId>detail-service</artifactId> <version>${project.version}</version> <!-- 这个版本就表示0.0.1-SNAPSHOT --> </dependency>  <!--注意这个包就是项目自己的模块--> <dependency> <groupId>com.drawcode</groupId> <artifactId>detail-client</artifactId> <version>${project.version}</version> </dependency> </dependencies> </dependencyManagement>  <build> <plugins> <!-- 注意此处为空 --> </plugins> </build>  </project> 复制代码

二、detail-start 的 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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
 <!--parent使用的即为父pom.xml的信息--> <parent> <groupId>com.drawcode</groupId> <artifactId>detail-page</artifactId> <version>0.0.1-SNAPSHOT</version> <relativePath>../pom.xml</relativePath> </parent>  <modelVersion>4.0.0</modelVersion> <artifactId>detail-start</artifactId> <packaging>jar</packaging> <!-- 注意此处要配置为jar --> <name>detail-start</name>  <!--子pom.xml没必要添加dependencyManagement--> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>  <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency>  <!--这里能够看到由于父pom.xml已经引用了自身项目的包模块,因此这里能够不加version直接使用--> <dependency> <groupId>com.drawcode</groupId> <artifactId>detail-service</artifactId> </dependency>  </dependencies>  <build> <plugins> <!--由于启动类在detail-start中,因此此处必须添加该plugin--> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>  </project> 复制代码

三、detail-service 的 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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
 <parent> <groupId>com.drawcode</groupId> <artifactId>detail-page</artifactId> <version>0.0.1-SNAPSHOT</version> <relativePath>../pom.xml</relativePath> <!-- lookup parent from repository --> </parent>  <modelVersion>4.0.0</modelVersion> <artifactId>detail-service</artifactId> <packaging>jar</packaging> <name>detail-service</name>  <!--detail-service依赖于detail-client--> <dependencies> <dependency> <groupId>com.drawcode</groupId> <artifactId>detail-client</artifactId> </dependency> </dependencies> </project> 复制代码

四、detail-start 的 pom.xml

由于 detail-start 没有任何依赖因此比较简单

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
 <parent> <groupId>com.drawcode</groupId> <artifactId>detail-page</artifactId> <version>0.0.1-SNAPSHOT</version> <relativePath>../pom.xml</relativePath> <!-- lookup parent from repository --> </parent>  <modelVersion>4.0.0</modelVersion> <artifactId>detail-client</artifactId> <packaging>jar</packaging> <name>detail-client</name>  <dependencies> </dependencies>  <build> </build>  </project> 复制代码

经过上述文件咱们能够分析出如下关系:

- detail-page:父模块
  - detail-client:子模块,无依赖
  - detail-service:子模块,依赖detail-client
  - detail-start:子模块,依赖detail-service
复制代码

注意:在依赖引用过程当中,千万不能够出现循环依赖,好比 client 引用了 service,service 也引用了 client,若是出现这种状况 maven 在打包的时候会直接报错

其中建议除了各个子模块单独使用的包以外,其余的都要在父模块下的 pom.xml 中配置包信息,这样便于包的版本控制

项目内部存在了包的依赖以后,不一样模块之间的代码便可进行使用,好比 detail-service 依赖 detail-client,那么 detail-client 中的 Test2 就能够被 detail-service 使用了

可是反过来 detail-client 不可使用 detail-service 中的类,由于依赖是单向的关系

如何启动

启动指令以下

$ mvn clean install && mvn spring-boot:run -pl detail-start
复制代码

其中 spring-boot:run 可使用就是由于 spring-boot-maven-plugin 的存在

-pl detail-start 则表明的是有 application 启动类的子模块目录

参考代码

https://github.com/guanpengchn/detail-page/tree/demo1

本文使用 mdnice 排版

相关文章
相关标签/搜索