Maven真——聚合和继承(于)

依赖管理
我们谈论继承一个dependencies因素,我们非常easy这个特性被认为是适用于accout-parent于。

子模块account-email和account-persist同一时候依赖了org.springframework:spring-core:2.5.6,spring-beans:2.5.6,spring-context:2.5.6,junit:junit:4.7。以此能够将这些公共依赖放到父模块account-parent中,两个子模块就能移除这些依赖,简化配置。
上述方法时可行的,可是有问题。

由于我们无法确定将来加入子模块就一定须要这四个模块依赖。

Maven提供dependencyManagement元素既能让子模块继承到父模块的依赖配置。又能保证子模块依赖使用的灵活性。在dependencyManagement元素下依赖声明不会引入实际的依赖。只是他能够约束dependencies下依赖的使用。

比如。能够在account-parent下加入这样的dependencyManagement配置,代码例如以下:

<modelVersion>4.0.0</modelVersion>
<groupId>com.juvenxu.mvnbook.account</groupId>
<artifactId>account-parent</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>pom</packaging>
<name>Account Parent</name>
<properties>
    <springframework.version>2.5.6</springframework.version>
    <junit.version>4.7</junit.version>
</properties>
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${springframework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>${springframework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${springframework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>${springframework.version}</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

如今改动account-email配置例如以下

<properties>
    <javax.mail.version>1.4.1</javax.mail.version>
    <greenmail.version>1.3.1b</greenmail>
</properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${springframework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>${springframework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${springframework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>${springframework.version}</version>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>${junit.version}</version>
        </dependency>
        <dependency>
            <groupId>javax.mail</groupId>
            <artifactId>mail</artifactId>
            <version>${junit.mail.version}</version>
        </dependency>
        <dependency>
            <groupId>com.icegreen</groupId>
            <artifactId>greenmail</artifactId>
            <version>${greenmail.version}</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

使用这样的依赖管理机制似乎不能降低太多了POM配置,可是我还是强烈推荐採用这样的方法。

原因是在于父pom中使用dependencyManagement声明依赖能够统一项目范围中依赖的版本号,降低依赖的冲突。
假设子模块中不声明依赖的使用,即使该依赖已经在父pom的dependencyManagement中声明了也不会产生不论什么实际的效果,假设account-persist:

<properties>
        <dom4j.version>1.6.1</dom4j.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>dom4j</groupId>
            <artifactId>dom4j</artifactId>
            <version>${dom4j.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${springframework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>${springframework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${springframework.version}</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>${junit.version}</version>
        </dependency>
    </dependencies>

这里没有声明spring-context-support。那么该依赖就不会被引入。
这里顺便提一下import的依赖范围,这个依赖范围仅仅在dependencyManagement元素下才有效果。使用该范围的依赖通常指向一个POM,作用是将目标POM中的dependencyManagement配置导入并合并到当前pom的dependencyManagement元素中。比如:

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>com.juvenxu.mvnbook.account</groupId>
                <artifactId>account-parent</artifactId>
                <version>1.0-SNAPSHOT</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

插件管理
Maven提供了dependencyManagement元素帮助管理依赖,相似的Maven也提供了pluginManagement元素帮助管理插件。在该元素中配置的依赖不会造成实际的插件调用行为,当POM中配置了真正了plugin元素,而且其groupId和artifactId与pluginManagement中配置的插件匹配时。pluginManagement的配置才会影响到实际的插件行为
比如:

<bulid>
    <pluginManagement>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-source-plugin</artifactId>
                <version>2.1.1</version>
                <executions>
                    <execution>
                        <id>attach-sources</id>
                        <phase>verify</phase>
                        <goals>
                            <goal>jar-no-fork</goal>
                        </goals>
                    <execution>
                </executions>
            </plugin>
        </plugins>
    </pluginManagement>
</bulid>

将其jar-no-fork目标绑定到了verity生命周期阶段,以生成项目源代码包,当子模块须要生成源代码包的时候,仅仅须要例如以下简单的配置。代码例如以下:

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

假设子模块须要不同于父模块的插件配置,能够自行配置以覆盖父模块的pluginManagement配置。有了pluginManagement元素,account-email和account-persist的pom也得以简化。

他们都配置了maven-compiler-plugin和maven-resoureces-plugin。能够将这两个插件配置移到account-parent的pluginManagement元素中。

<build>
    <pluginManagement>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.5</source>
                    <target>1.5</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-resources-plugin</artifactId>
                <configuration>
                    <encoding>UTF-8</encoding>
                </configuration>
        </plugins>
    </pluginManagement>
</build>

account-email和accoun-persist能够全然移除关于maven-compiler-plugin和maven-resources-plugin的配置,但他们仍能享受这两个插件服务。
当项目的多个模块有相同的插件配置时,应当将配置移到父pom的pluginManagement的元素中。

即使各个模块对同一个插件的详细配置不尽相同,也应当使用父pom的pluginManagement元素统一声明插件的版本号。甚至能够要求将全部用到的插件的版本号在父pom的pluginManagement元素中声明,子模块使用插件时不配置版本号信息。这么做能够统一项目的插件版本号,避免潜在的插件不一致或者不稳定问题。也更易于维护。

posted @ 2015-09-18 19:31  hrhguanli  阅读(251)  评论(0编辑  收藏  举报