大廠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 排版

相關文章
相關標籤/搜索