Maven管理多模塊應用


穿越至目錄:

從0開始,構建前后端分離應用

 

對於概念的一些理解

Maven的作用

管理模塊之間的依賴:根據業務需求,系統會划分很多模塊,這些模塊彼此之間存在着依賴關系。比如系統管理模塊依賴着文件上傳模塊,來實現用戶頭像上傳的功能。maven通過配置模塊之間的pom依賴

生命周期管理:在web應用中,我們常要進行編譯、打包、測試這些環節。在maven的世界里,將這些過程定義為生命周期。maven將這些復雜的過程進行了封裝,使用者只需要簡單的用鼠標點幾下就可以完成項目的構建工作

強大的插件:舉一個很常用的插件tomcat7-maven-plugin,在老老年間,我們發布應用的方式是,將web應用打包成war->手動拷貝到tomcat的webapp目錄下->啟動tomcat。現在有了Maven以上過程我們只需要點擊一下鼠標即可完成。是不是很方便?

倉庫式管理:曾經為了找一個jar包費勁周折,曾經因為jar包沖突、版本產生莫名其妙的問題困擾我們好久。Maven提供的公用倉庫http://mvnrepository.com/,只要輸入jar包的坐標即可查找到想要的資源,將模塊的坐標加入到自己的pom中就可以快樂的使用了,真的覺得很方便。同時由於依賴的概念,與其相關的jar包也會引入到項目環境中,並且不會產生版本的問題

Nexus作用

節省流量:Nexus作為私有庫部署在局域網內部,比如10個人協同開發,開發人員A需要一個log4j的jar來實現系統日志功能,A將log4j的坐標添加到自己模塊的pom文件中,maven會向公共倉庫發送請求,下載log4j的jar包。下載的過程中,Nexus也偷偷的保存了一份log4j在私有的倉庫。那么以后再有開發人員需要log4j的時候,請求是直接發送到Nexus上請求資源的。就不需要訪問外網了,否則每個人都需要訪問公共Maven庫下載資源。這樣節省了流量,同時內網的網速一般也比公網快。也提高了工作效率

協同開發:多人協同開發,A開發系統管理、B開發考勤模塊。考勤模塊依賴了系統管理的員工接口,那么B需要手動拷貝A打包的jar到自己的工程中。當A改動了系統管理的接口,B完全不知情,等出現問題了還需要聯調,很麻煩!有了Nexus A就可以將系統管理打包發布到Nexus的私有倉庫中,B添加系統管理的坐標即可完成依賴,以后A再有改動,只要發布到Nexus上就可以了。減少了溝通成本

場景描述

項目的模塊結構

大概是這個樣子

commonModal:提供公共的基礎服務,比如文件上傳、郵件發送、權限管理等等

businessModal:業務模塊,是系統真正要實現的業務。依賴於commonModal,比如訂單管理、財務統計、會員管理等

application:可發布的web應用,由各個businessModal組成,最終滿足項目的整體需求

第三方模塊:包括各類框架,spring、mybatis、日志等。整個應用都是依賴它們完成開發的

 

如何使用Maven管理以上的結構呢?

首先要弄清楚Maven的兩個重要的概念,依賴和繼承。舉例說明:

場景:

1、有A、B、C三個模塊是用Maven進行管理的,它們之間的關系:C依賴B、B依賴A

2、有D、E、F三個模塊是用Maven進行管理的。它們之間的關系:F繼承自E,也就是F的parent是E。E依賴D

結果:

依賴:對於場景1,由於依賴的傳遞性,C模塊中,除了能使用B的接口外,同時也能使用A的接口。但是在C模塊中,無法繼承到B模塊的一些POM配置(比如<properties>定義的版本信息,<build>中定義構建信息等)

繼承:對於場景2,F是能夠繼承到E的Pom的配置的,比如對E對D的依賴,在F中是能夠使用D中定義的接口的。還有其他的Pom配置,比如<properties>、<build>、<distributionManagement>

 

回到主題,對於上述的模塊結構,如果使用maven管理應該考慮的問題有哪些呢?

1、隨着項目的進展,模塊的數量不斷增長。maven對於模塊的管理包含着版本的概念,只有正確的管理版本,才不至於在工作中造成版本的混亂。

    是否應該有一個地方統一對版本進行管理?

2、對於所有的模塊,是都需要發布到nexus上進行管理的,那么是否代表着,沒一個模塊都要配置<distributionManagement>來對發布過程進行管理呢?如果nexus服務器ip換了怎么辦?每個模塊去修改?

    應該有一個地方統一管理整個項目的發布配置

3、對於依賴的管理,通過模塊結構圖可以想象,模塊之間的依賴是很復雜的,比如很多模塊都依賴於log4j,是否每個模塊都要使用<dependency>一次Log4j

實戰

基於以上的問題,將Maven的管理結構定義如下,有maven模塊之間的關系和類之間的關系非常接近,因此使用類圖表示

 

圖解:

上圖中綠色部分為Maven管理模塊,打包類型為pom。

root:抽象層級最高的模塊,應該配置公用級別最高的配置。也就是所有模塊都需要用到的發布到nexus上的配置。那么其他所有層級的模塊就可以共享這一配置,比如commonModal就可以通過路徑5-4-3-1繼承到<distributionManagement>配置。這樣問題2就得到了解決

version、modalVersion、businessVersion:為版本定義模塊,分別定義了第三方模塊、commonModal、businessModal的版本信息。這樣就解決了問題1

j2ee、modalGather:分別持有對第三方模塊、commonModal的依賴。application、businessModal、commonModal都可以通過繼承路徑,獲取到上層的資源。也就不必要在所有的模塊中都重復的進行引用操作

具體配置

root模塊的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.wt.common</groupId>
    <artifactId>root</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>pom</packaging>
    <name>root</name>

    <developers>
        <developer>
            <name>lichking</name>
            <email>lichking2017@aliyun.com</email>
        </developer>
    </developers>

    <properties>
        <project.build.sourceEncoding>1.8</project.build.sourceEncoding>
        <version.j2ee>1.0-SNAPSHOT</version.j2ee>
    </properties>

    <!--構建設置-->
    <build>
        <outputDirectory>${basedir}/target/${project.build.finalName}/WEB-INF/classes</outputDirectory>
        <plugins>
            <!--設置編譯的jdk版本還有編碼格式-->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.7.0</version>
                <configuration>
                    <encoding>UTF-8</encoding>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
            <!--設置資源文件讀取編碼格式-->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-resources-plugin</artifactId>
                <version>3.0.2</version>
                <configuration>
                    <encoding>${project.build.sourceEncoding}</encoding>
                </configuration>
            </plugin>

            <!--源碼打包-->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-source-plugin</artifactId>
                <version>2.4</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>jar-no-fork</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

    <!--配置發布信息-->
    <distributionManagement>
        <repository>
            <id>releases</id>
            <url>http://192.168.0.110:8081/repository/maven-releases/</url>
        </repository>
        <snapshotRepository>
            <id>snapshots</id>
            <url>http://192.168.0.110:8081/repository/maven-snapshots/</url>
        </snapshotRepository>
    </distributionManagement>
</project>

 

 version模塊的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>root</artifactId>
        <groupId>com.wt.common</groupId>
        <version>1.0-SNAPSHOT</version>
        <relativePath>../root/pom.xml</relativePath>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.wt.common</groupId>
    <artifactId>version</artifactId>
    <packaging>pom</packaging>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <version.spring>5.0.2.RELEASE</version.spring>
        <version.com.google.code.gson>2.8.2</version.com.google.code.gson>
        <version.commons-lang3>3.7</version.commons-lang3>
        <version.druid>1.1.9</version.druid>
        <version.mybatis>3.4.6</version.mybatis>
        <version.mybatis-spring>1.3.2</version.mybatis-spring>
        <version.mybatis-generator>1.0SNAPSHOT</version.mybatis-generator>
        <version.core>1.0-SNAPSHOT</version.core>
        <version.mysql.driver>6.0.6</version.mysql.driver>
        <version.gson>2.8.2</version.gson>
        <version.junit>4.12</version.junit>
        <version.testng>6.14.3</version.testng>
        <slf4j.version>1.7.25</slf4j.version>
        <log4j.version>2.8.2</log4j.version>
    </properties>
</project>

 

 j2ee模塊的配置:

<?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>version</artifactId>
        <groupId>com.wt.common</groupId>
        <version>1.0-SNAPSHOT</version>
        <relativePath>../version/pom.xml</relativePath>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.wt.common</groupId>
    <artifactId>j2ee</artifactId>
    <packaging>pom</packaging>
    <name>j2ee</name>

    <dependencies>
        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-api</artifactId>
            <version>7.0</version>
            <scope>compile</scope>
        </dependency>

        <!--通過傳遞依賴,已經將spring-core、context、aop、beans模塊加入到了依賴樹中-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${version.spring}</version>
        </dependency>
        <!-- spring事物模塊 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>${version.spring}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>${version.spring}</version>
        </dependency>
        <!--apache工具包-->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>${version.commons-lang3}</version>
        </dependency>
        <!--前后端通過json通信-->
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>${version.com.google.code.gson}</version>
        </dependency>
        <!--數據庫連接池-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>${version.druid}</version>
        </dependency>
        <!--mysql數據庫連接驅動-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>${version.mysql.driver}</version>
        </dependency>
        <!-- controller向客戶端返回數據的時候,表述形式為JSON時,需要的依賴(google的gson工具) -->
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>${version.gson}</version>
        </dependency>
        <!--mybatis依賴begin-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>${version.mybatis}</version>
        </dependency>
        <!--mybatis與spring整合-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>${version.mybatis-spring}</version>
        </dependency>
        <!--&lt;!&ndash;mybatis 代碼生成器&ndash;&gt;-->
        <!--<dependency>-->
        <!--<groupId>org.mybatis.generator</groupId>-->
        <!--<artifactId>mybatis-generator-core</artifactId>-->
        <!--<version>${version.mybatis-generator}</version>-->
        <!--</dependency>-->
        <!--框架依賴-->
        <dependency>
            <groupId>com.wt.common</groupId>
            <artifactId>core</artifactId>
            <version>${version.core}</version>
        </dependency>
        <!--日志處理-->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>${slf4j.version}</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>jcl-over-slf4j</artifactId>
            <version>${slf4j.version}</version>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-api</artifactId>
            <version>${log4j.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>${log4j.version}</version>
        </dependency>
        <!--用於與sfl4j保持橋接-->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-slf4j-impl</artifactId>
            <version>${log4j.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-web</artifactId>
            <version>${log4j.version}</version>
            <scope>runtime</scope>
        </dependency>

        <!--測試框架-->
        <dependency>
            <groupId>org.testng</groupId>
            <artifactId>testng</artifactId>
            <version>${version.testng}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>${version.junit}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>${version.spring}</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <!--<build>-->
    <!--<plugins>-->
    <!--<plugin>-->
    <!--<groupId>org.mybatis.generator</groupId>-->
    <!--<artifactId>mybatis-generator-maven-plugin</artifactId>-->
    <!--<version>${version.mybatis-generator}</version>-->
    <!--</plugin>-->
    <!--</plugins>-->
    <!--</build>-->
</project>

moduleVersion模塊的配置

<?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>j2ee</artifactId>
        <groupId>com.wt.common</groupId>
        <version>1.0-SNAPSHOT</version>
        <relativePath>../j2ee/pom.xml</relativePath>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.wt.common</groupId>
    <artifactId>moduleVersion</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>pom</packaging>

    <properties>
        <version.security>1.0-SNAPSHOT</version.security>
        <version.upload>1.0-SNAPSHOT</version.upload>
        <version.core>1.0-SNAPSHOT</version.core>
    </properties>

</project>

 

 modalGather模塊的配置

<?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>moduleVersion</artifactId>
        <groupId>com.wt.common</groupId>
        <version>1.0-SNAPSHOT</version>
        <relativePath>../moduleVersion/pom.xml</relativePath>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.wt.common</groupId>
    <artifactId>modalGather</artifactId>
    <packaging>pom</packaging>


    <dependencies>
        <dependency>
            <groupId>com.wt.common</groupId>
            <artifactId>security</artifactId>
            <version>${version.security}</version>
        </dependency>

        <dependency>
            <groupId>com.wt.common</groupId>
            <artifactId>upload</artifactId>
            <version>${version.upload}</version>
        </dependency>

        <dependency>
            <groupId>com.wt.common</groupId>
            <artifactId>core</artifactId>
            <version>${version.core}</version>
        </dependency>
    </dependencies>

</project>

 

以上就是個人的一些見解

 

 

其他

關於Maven與nexus的結合使用,搞清楚幾點就可以:

1、在項目中配置模塊的發布路徑,如上文提到的root的配置

其中的<repository><snapshotRepository>是固定寫法,分別對應snapshot版本和release版本

<id>是要注意的,一定要與你本地的setting中的<server>中的id對應上,Maven才能通過id對應的用戶名和密碼連接到nexus

2、<url>中的內容是哪來的?

它對應着nexus倉庫中的配置,見下圖nexus中的紅箭頭,點擊一下就可以拷貝對應的地址了

<distributionManagement>
        <repository>
            <id>releases</id>
            <url>http://192.168.0.110:8081/repository/maven-releases/</url>
        </repository>
        <snapshotRepository>
            <id>snapshots</id>
            <url>http://192.168.0.110:8081/repository/maven-snapshots/</url>
        </snapshotRepository>
    </distributionManagement>

以下是本機settings.xml配置

<?xml version="1.0" encoding="UTF-8"?>
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
  <servers>
    <server>
      <id>nexus</id>
      <username>admin</username>
      <password>admin123</password>
    </server>
    <server>
      <id>snapshots</id>
      <username>admin</username>
      <password>admin123</password>
    </server>
    <server>
      <id>tomcat8</id>
      <username>admin</username>
      <password>admin</password>
    </server>
  </servers>

  <mirrors>
    <!-- 本地nexus私服
    <mirror>
      <id>nexus</id>
      <mirrorOf>*</mirrorOf>
      <url>http://192.168.0.240:8081/nexus/content/groups/public/</url>
    </mirror>
    -->
    <!-- 阿里雲倉庫
        <mirror>
            <id>alimaven</id>
            <mirrorOf>*</mirrorOf>
            <name>aliyun maven</name>
            <url>http://maven.aliyun.com/nexus/content/repositories/central/</url>
        </mirror>
    -->
    <mirror>
      <id>nexus</id>
      <mirrorOf>*</mirrorOf>
      <url>http://192.168.0.110:8081/repository/maven-public/</url>
    </mirror>
  </mirrors>

  <profiles>
<profile>
      <id>nexus</id>
      <repositories>
        <repository>
          <id>nexus</id>
          <name>Nexus</name>
          <!--
          <url>http://192.168.0.240:8081/nexus/content/groups/public/</url>
          -->
          <url>http://192.168.0.110:8081/repository/maven-public/</url>
          <releases><enabled>true</enabled><updatePolicy>always</updatePolicy></releases>
          <snapshots><enabled>true</enabled><updatePolicy>always</updatePolicy></snapshots>
        </repository>
      </repositories>
      <pluginRepositories>
        <pluginRepository>
          <id>nexus</id>
          <name>Nexus</name>
      <!--
          <url>http://192.168.0.240:8081/nexus/content/groups/public/</url>
          -->
      <url>http://192.168.0.110:8081/repository/maven-public/</url>
      <releases><enabled>true</enabled><updatePolicy>always</updatePolicy></releases>
          <snapshots><enabled>true</enabled><updatePolicy>always</updatePolicy></snapshots>
        </pluginRepository>
      </pluginRepositories>
</profile>
  </profiles>

<activeProfiles>
    <activeProfile>nexus</activeProfile>
  </activeProfiles>
</settings>

 

 

另外Nexus3相對2改進還是很多的,界面也很炫酷,可以嘗試一下

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM