天天看點

Maven pom.xml中的元素modules、parent、properties以及import

前言

  項目中用到了maven,而且用到的内容不像利用maven/eclipse搭建ssm(spring+spring mvc+mybatis)用的那麼簡單

  maven的核心是 pom.xml,那麼我們就來看看那些不同的地方

  給我印象最深的就是如下四個元素:modules、parent、properties、import

modules

  從字面意思來說,module 就是子產品,而 pom.xml 中的 modules 也正是這個意思,用來管理同個項目中的各個子產品

  如果 maven 用的比較簡單,或者說項目的子產品在 pom.xml 沒進行劃分,那麼此元素是用不到的

  稍微複雜一點的項目都是要用到的

  需求場景

    如果我們的項目分成了好幾個子產品,那麼我們建構的時候是不是有幾個子產品就需要建構幾次了(到每個子產品的目錄下執行 mvn 指令)?

    當然,你逐個建構沒問題,但是非要這麼麻煩的一個一個的建構嗎

    簡單的做法就是使用聚合,一次建構全部子產品

  具體實作

    既然使用聚合,那麼就需要一個聚合的載體,先建立一個普通的 maven 項目 account-aggregator,如下圖:

  

    因為是個聚合體,僅僅負責聚合其他子產品,那麼就隻需要上述目錄,該删除的就删了

    注意 pom.xml 中的紅色部分

<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.youzhibing.account</groupId>
  <artifactId>account-aggregator</artifactId>
  <version>1.0.0-SNAPSHOT</version>
  <packaging>pom</packaging>

  <name>Account Aggrregator</name>
  <url>http://maven.apache.org</url>
  
  <modules>
    <!-- 子產品都寫在此處 -->
      <module>account-register</module>
      <module>account-persist</module>
  </modules>

</project>      

    建立子模 account-register、account-persist

    右擊 account-aggregator,new --> other --> Maven,選擇 Maven Module,建立 moven 子產品

    建立完成後,項目結構如下,那麼此時 account-aggregator 可以收縮起來了,我們操作具體子子產品就好了

Maven pom.xml中的元素modules、parent、properties以及import

     當我們打開包結構的子子產品的 pom.xml 時,發現比預期的多了一些内容,我們做下處理就好了

    那麼編碼完了之後,我們隻需要建構 account-aggregator 就好了,所有的子子產品都會建構

parent

  繼承,和 java 中的繼承相當,作用就是複用

    若每個子子產品都都用的了 spring,那麼我們是不是每個子子產品都需要單獨配置 spring依賴了?

    這麼做是可以的,但是我們有更優的做法,那就是繼承,用 parent 來實作

    配置父 pom.xml

      我們就用聚合pom來做父pom,配置子子產品的公共依賴

      父(account-aggregator) pom.xml

Maven pom.xml中的元素modules、parent、properties以及import
Maven pom.xml中的元素modules、parent、properties以及import
<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.youzhibing.account</groupId>
  <artifactId>account-aggregator</artifactId>
  <version>1.0.0-SNAPSHOT</version>
  <packaging>pom</packaging>

  <name>Account Aggrregator</name>
  <url>http://maven.apache.org</url>
  
  <modules>
      <!-- 子產品都寫在此處 -->
      <module>account-register</module>
      <module>account-persist</module>
  </modules>
  
  <dependencies> <!-- 配置共有依賴 -->
      <!-- spring 依賴 -->
      <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>4.0.2.RELEASE</version>
    </dependency>
      <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-beans</artifactId>
        <version>4.0.2.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>4.0.2.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context-support</artifactId>
        <version>4.0.2.RELEASE</version>
    </dependency>
    
      <!-- junit 依賴 -->
      <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.7</version>
      <scope>test</scope>
    </dependency>
  </dependencies>

</project>      

View Code

    account-register 的 pom.xml

Maven pom.xml中的元素modules、parent、properties以及import
Maven pom.xml中的元素modules、parent、properties以及import
<?xml version="1.0"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>com.youzhibing.account</groupId>
    <artifactId>account-aggregator</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <relativePath>../pom.xml</relativePath> <!-- 與不配置一樣,預設就是尋找上級目錄下得pom.xml -->
  </parent>
  <artifactId>account-register</artifactId>
  <name>account-register</name>
  <url>http://maven.apache.org</url>
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>
  <dependencies>    <!-- 配置自己獨有依賴 -->
      <dependency>
          <groupId>javax.mail</groupId>
          <artifactId>mail</artifactId>
          <version>1.4.3</version>
      </dependency>
    <dependency>
      <groupId>com.icegreen</groupId>
      <artifactId>greenmail</artifactId>
      <version>1.4.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project>      

    account-persist 的 pom.xml

Maven pom.xml中的元素modules、parent、properties以及import
Maven pom.xml中的元素modules、parent、properties以及import
<?xml version="1.0"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>com.youzhibing.account</groupId>
    <artifactId>account-aggregator</artifactId>
    <version>1.0.0-SNAPSHOT</version>
  </parent>
  <artifactId>account-persist</artifactId>
  <name>account-persist</name>
  <url>http://maven.apache.org</url>
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>
  <dependencies>    <!-- 配置自己獨有依賴 -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
        <version>4.0.2.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid</artifactId>
        <version>1.0.16</version>
    </dependency>
  </dependencies>
</project>      

    依賴的 jar 包全部 ok,需要做的則是在各個子產品中進行代碼開發了!

  依賴管理

    繼承可以消除重複,那是不是就沒有問題了? 還是有小瑕疵的

    假設将來需要添加一個新的子子產品account-util,該子產品隻是提供一些簡單的幫助工具,不需要依賴spring、junit,那麼繼承後就依賴上了,有沒有什麼辦法了?

    有,maven已經替我們想到了,那就是 dependencyManagement 元素,既能讓子子產品繼承到父子產品的依賴配置,又能保證子子產品依賴使用的靈活性

    在 dependencyManagement 元素下得依賴聲明不會引入實際的依賴,不過它能夠限制 dependencies 下的依賴使用

    在父 pom.xml 中配置 dependencyManagement 元素

Maven pom.xml中的元素modules、parent、properties以及import
Maven pom.xml中的元素modules、parent、properties以及import
<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.youzhibing.account</groupId>
  <artifactId>account-aggregator</artifactId>
  <version>1.0.0-SNAPSHOT</version>
  <packaging>pom</packaging>

  <name>Account Aggrregator</name>
  <url>http://maven.apache.org</url>
  
  <modules>
      <!-- 子產品都寫在此處 -->
      <module>account-register</module>
      <module>account-persist</module>
  </modules>
  
  <dependencyManagement>
      <dependencies> <!-- 配置共有依賴 -->
      <!-- spring 依賴 -->
      <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>4.0.2.RELEASE</version>
    </dependency>
      <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-beans</artifactId>
        <version>4.0.2.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>4.0.2.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context-support</artifactId>
        <version>4.0.2.RELEASE</version>
    </dependency>
    
      <!-- junit 依賴 -->
      <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.7</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
  </dependencyManagement>
</project>      

    account-persist的pom.xml(account-register也一樣) :

Maven pom.xml中的元素modules、parent、properties以及import
Maven pom.xml中的元素modules、parent、properties以及import
<?xml version="1.0"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>com.youzhibing.account</groupId>
    <artifactId>account-aggregator</artifactId>
    <version>1.0.0-SNAPSHOT</version>
  </parent>
  <artifactId>account-persist</artifactId>
  <name>account-persist</name>
  <url>http://maven.apache.org</url>
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>
  <dependencies>
      <!-- spring 依賴 -->
      <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
    </dependency>
      <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-beans</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context-support</artifactId>
    </dependency>
    
      <!-- junit 依賴 -->
      <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
        <version>4.0.2.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid</artifactId>
        <version>1.0.16</version>
    </dependency>
  </dependencies>
</project>      

    使用這種依賴管理機制似乎不能減少太多的POM配置,就少了version(junit還少了個scope),感覺沒啥作用呀

    其實作用還是挺大的,父 pom.xml 使用 dependencyManagement 能夠統一項目範圍中依賴的版本

    當依賴版本在父POM中聲明後,子子產品在使用依賴的時候就無須聲明版本,也就不會發生多個子子產品使用版本不一緻的情況,幫助降低依賴沖突的幾率

    如果子子產品不聲明依賴的使用,即使該依賴在父 pom.xml 中的 dependencyManagement 中聲明了,也不會産生任何效果

import

  import 隻在 dependencyManagement 元素下才有效果,作用是将目标 pom.xml 中的 dependencyManagement 配置導入并合并到目前 pom.xml 的 dependencyManagement 元素中

  如下就是講 account-aggregator中 的 dependencyManagement 配置導入并合并到目前 pom.xml 中

<dependencyManagement>
      <dependencies>
        <dependency>
            <groupId>com.youzhibing.account</groupId>
              <artifactId>account-aggregator</artifactId>
              <version>1.0.0-SNAPSHOT</version>
            <type>pom</type>
              <scope>import</scope>
        </dependency>
      </dependencies>
  </dependencyManagement>      

properties

  通過 properties 元素使用者可以自定義一個或多個 maven 屬性,然後在 pom.xml 的其他地方使用 ${屬性名} 的方式引用該屬性,這種做法的最大意義在于消除重複和統一管理

  maven 總共有 6 類屬性,内置屬性、POM屬性、自定義屬性、Settings屬性、java系統屬性和環境變量屬性

  内置屬性

    兩個常用内置屬性 ${basedir} 表示項目跟目錄,即包含 pom.xml 檔案的目錄;${version} 表示項目版本

  pom 屬性

    使用者可以使用該類屬性引用POM檔案中對應元素的值。如${project.artifactId}就對應了<project> <artifactId>元素的值,常用的POM屬性包括:

    ${project.build.sourceDirectory}:項目的主源碼目錄,預設為src/main/java/

    ${project.build.testSourceDirectory}:項目的測試源碼目錄,預設為src/test/java/

    ${project.build.directory} : 項目建構輸出目錄,預設為target/

    ${project.outputDirectory} : 項目主代碼編譯輸出目錄,預設為target/classes/

    ${project.testOutputDirectory}:項目測試主代碼輸出目錄,預設為target/testclasses/

    ${project.groupId}:項目的groupId

    ${project.artifactId}:項目的artifactId

    ${project.version}:項目的version,與${version} 等價

    ${project.build.finalName}:項目打包輸出檔案的名稱,預設為${project.artifactId}-${project.version}

  自定義屬性

    如下 account-aggregator 的 pom.xml,那麼繼承了此 pom.xml 的子子產品也可以用此自定義屬性

Maven pom.xml中的元素modules、parent、properties以及import
Maven pom.xml中的元素modules、parent、properties以及import
<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.youzhibing.account</groupId>
  <artifactId>account-aggregator</artifactId>
  <version>1.0.0-SNAPSHOT</version>
  <packaging>pom</packaging>

  <name>Account Aggrregator</name>
  <url>http://maven.apache.org</url>
  
  <modules>
      <!-- 子產品都寫在此處 -->
      <module>account-register</module>
      <module>account-persist</module>
      <module>account-another</module>
  </modules>
  
  <properties>
      <!-- 定義 spring版本号 -->
    <spring.version>4.0.2.RELEASE</spring.version>
    <junit.version>4.7</junit.version>
  </properties>
  
  <dependencyManagement>
      <dependencies> <!-- 配置共有依賴 -->
      <!-- spring 依賴 -->
      <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>${spring.version}</version>
    </dependency>
      <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-beans</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context-support</artifactId>
        <version>${spring.version}</version>
    </dependency>
    
      <!-- junit 依賴 -->
      <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>${junit.version}</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
  </dependencyManagement>
</project>      

  settings屬性

    與 pom 屬性同理,使用者使用以 settings. 開頭的屬性引用 settings.xml 檔案中的 XML 元素的值

  Java系統屬性

    所有 java 系統屬性都可以用 maven 屬性引用,如 ${user.home} 指向了使用者目錄

  環境變量屬性

    所有環境變量屬性都可以使用以 env. 開頭的 maven 屬性引用,如 ${env.JAVA_HOME} 指代了 JAVA_HOME 環境變量的的值

聚合與繼承的關系

  1、聚合主要是為了友善快速建構項目,繼承主要是為了消除重複配置

  2、對于聚合子產品而言,它知道有哪些被聚合的子產品,但那些被聚合的子產品不知道這個聚合子產品的存在;對于繼承的父pom 而言,它不知道有哪些子子產品繼承它,但那些子子產品都必須知道自己的父pom 是什麼

  3、聚合pom 與繼承中的父pom 的 packaging 都必須是 pom;同時,聚合子產品與繼承中的父子產品除了 pom 外,都沒有實際的内容

結束語

  maven越來越流行,這方面的資料也是越來越多,《Maven實戰》給我的感覺就相當不錯,本部落格的内容大多取自其中;網上資料也越來越多,就部落格園中就有不少;

  最後強調一點:看了是好,實踐更好,寫部落格記錄下來那是最好!