Maven的聚合和繼承(六)

jopen 8年前發布 | 8K 次閱讀 Maven 項目構建

    我們使用Maven應用到實際項目的時候,需要將項目分成不同的模塊。這個時候,Maven的聚合特性能夠把項目的各個模塊聚合在一起構件,而Maven的繼承特性則能幫助抽取各模塊相同的依賴和插件等配置。在簡化POM的同時,還能促進各個模塊配置的一致性。下面以具體項目來講解:

1. 項目結構


以上有五個項目分別為user-parent, user-core, user-log, user-dao, user-service. 其中user-parent項目為其他項目的父項目,只是幫助其他模塊構建的工具,它本身并無實質的內容,只有一個pom.xml文件。

2. user-parent的pom.xml詳情如下(下文簡稱為父POM)

<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.liangbo.user</groupId>
  <artifactId>user-parent</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>pom</packaging>

  <modules>
      <module>../user-core</module>
      <module>../user-dao</module>
      <module>../user-log</module>
      <module>../user-service</module>
  </modules>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <junit.version>4.10</junit.version>
    <mysql.driver>com.mysql.jdbc.Driver</mysql.driver>
    <mysql.url>jdbc:mysql://localhost:3306/mysql</mysql.url>
    <mysql.username>root</mysql.username>
    <mysql.password>password</mysql.password>
  </properties>

  <dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>com.liangbo.user</groupId>
            <artifactId>user-core</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>

        <dependency>
            <groupId>com.liangbo.user</groupId>
            <artifactId>user-log</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>

        <dependency>
            <groupId>com.liangbo.user</groupId>
            <artifactId>user-dao</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>

        <dependency>
            <groupId>com.liangbo.user</groupId>
            <artifactId>user-log</artifactId>
            <version>0.0.1-SNAPSHOT</version>
            <exclusions>
                <exclusion>
                    <groupId>log4j</groupId>
                    <artifactId>log4j</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.9</version>
        </dependency>

        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.1.1</version>
        </dependency>

        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>3.6.10.Final</version>
        </dependency>

        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.16</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.26</version>
        </dependency>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.5</version>
        </dependency>

        <dependency>
            <groupId>javassist</groupId>
            <artifactId>javassist</artifactId>
            <version>3.12.1.GA</version>
        </dependency>

    </dependencies>
  </dependencyManagement>

  <build>
      <pluginManagement>
          <plugins>
              <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-source-plugin</artifactId>
                <version>2.2.1</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals><goal>jar-no-fork</goal></goals>
                    </execution>
                </executions>
            </plugin>

            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>sql-maven-plugin</artifactId>
                <version>1.5</version>
                <dependencies>
                    <dependency>
                        <groupId>mysql</groupId>
                        <artifactId>mysql-connector-java</artifactId>
                        <version>5.1.26</version>
                    </dependency>
                </dependencies>
                <configuration>
                    <driver>${mysql.driver}</driver>
                    <url>${mysql.url}</url>
                    <username>${mysql.username}</username>
                    <password>${mysql.password}</password>
                    <sqlCommand>
                        create database IF NOT EXISTS maven_test
                    </sqlCommand>
                </configuration>                
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>execute</goal>
                        </goals>
                    </execution>                
                </executions>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-rar-plugin</artifactId>
                <version>2.3</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals><goal>rar</goal></goals>
                    </execution>
                </executions>
            </plugin>
          </plugins>
      </pluginManagement>
  </build>
</project>

上面的pom.xml文件既有Maven的聚合特性又有繼承特性。這樣做是為了更加方便管理其他模塊。其中元素modules,是實現聚合的最核心配置。多個子模塊之間的pom有很多的相同的配置,這時候可以全部提取出來放到父項目中。重復往往就意味著更多的勞動和更多的潛在的問題。那么子模塊如何來繼承他的父項目呢?

3. 下面來看下user-core項目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>

  <parent>
      <groupId>com.liangbo.user</groupId>
      <artifactId>user-parent</artifactId>
      <version>0.0.1-SNAPSHOT</version>
      <relativePath>../user-parent/pom.xml</relativePath>
  </parent> 

  <artifactId>user-core</artifactId>
  <packaging>jar</packaging>

  <name>user-core</name>
  <url>http://maven.apache.org</url>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
    </dependency>

    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-core</artifactId>
    </dependency>

    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
    </dependency>

    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
    </dependency>

    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-log4j12</artifactId>
    </dependency>

    <dependency>
        <groupId>javassist</groupId>
        <artifactId>javassist</artifactId>
    </dependency>
  </dependencies>

  <build>
      <plugins>
          <plugin>
              <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-source-plugin</artifactId>
          </plugin>

          <plugin>
              <groupId>org.codehaus.mojo</groupId>
            <artifactId>sql-maven-plugin</artifactId>
          </plugin>

          <plugin>
              <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-rar-plugin</artifactId>
          </plugin>
      </plugins>
  </build>
</project>

其中設置好relativePath非常重要,不然無法找到父POM。這時候子POM中只需要配置groupId和artifactId就可以了。

4. 依賴管理和插件管理

上述子POM配置簡單了很多,是因為父POM引用了依賴管理和插件管理的概念。
如果父POM沒有配置依賴管理和插件管理的話,繼承它的子模塊會將父所有的依賴和插件都繼承下來,顯然這是不可行的。接下來講下如何配置的:

Maven提供的dependencyManagement元素既能讓子模塊繼承到父模塊的依賴配置,又能保證子模塊依賴使用的靈活性。在dependencyManagement元素下的依賴聲明不會引入實際的依賴,不過它可以約束dependencies下的依賴使用。插件管理同上,需要在父POM中加入pluginManagement元素。

最后,說下聚合與繼承的關系,多模塊Maven中的聚合與繼承其實是兩個不同的概念,其目的是不同的。前者主要是為了方便快速構建項目,后者主要是為了消除重復配置




來自: http://my.oschina.net/liangbo/blog/195405

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!