Maven的聚合和继承(六)

jopen 8年前

    我们使用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