maven-聚合和继承

Posted float123

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了maven-聚合和继承相关的知识,希望对你有一定的参考价值。

概述

聚合的动机是为了方便一起编译;继承的作用是为了统一依赖管理;搞清楚这两个方面就很容易使用他们了。依赖范围为 import 则是为了解决单继承问题。

聚合

例如我有一个 provider项目,该项目中又包含了 provider-bit 和 provider-api 两个子项目,provider 即使用了聚合,又使用了继承。我们来看一下 provider 根目录下的 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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.6.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <groupId>com.bbm</groupId>
    <artifactId>demo</artifactId>
    <version>1.0.0</version>
    <name>demo</name>
    <description>Demo project for Spring Boot</description>

    <!-- 父pom聚合了两个子项目,那么编译的时候就会一起编译 -->
    <modules>
        <module>provider-api</module>
        <module>provider-bit</module>
    </modules>

    <packaging>pom</packaging>

    <properties>
        <java.version>1.8</java.version>
        <curator-recipes.version>4.0.1</curator-recipes.version>
        <curator-framework.version>4.0.1</curator-framework.version>
        <zk.version>3.4.6</zk.version>
        <dubbo-version>2.7.6</dubbo-version>
        <spring-boot.version>2.2.6.RELEASE</spring-boot.version>
    </properties>


    <dependencyManagement>

        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter</artifactId>
                <version>${spring-boot.version}</version>
            </dependency>

            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <version>${spring-boot.version}</version>
                <scope>test</scope>
                <exclusions>
                    <exclusion>
                        <groupId>org.junit.vintage</groupId>
                        <artifactId>junit-vintage-engine</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>

            ...

        </dependencies>
    </dependencyManagement>



    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <skip>true</skip>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>


需要说明的使用了聚合,那么父pom.xml 中的打包方式就一定是 pom , 就是这一句 :

    <packaging>pom</packaging>

继承

而继承则是为了方便依赖的统一管理,例如 provider-bit 项目中的 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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <!-- 这里指明了父坐标,其中relativePath 指的是相对路径,最好是显式指明,默认是上一级的路径下-->
    <parent>
        <groupId>com.bbm</groupId>
        <artifactId>demo</artifactId>
        <version>1.0.0</version>
        <relativePath>../pom.xml</relativePath><!-- lookup parent from repository -->
    </parent>

    <artifactId>provider-bit</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>provider-bit</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>

        <dependency>
            <groupId>com.bbm</groupId>
            <artifactId>provider-api</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <!-- Dubbo Spring Boot Starter -->
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo</artifactId>
        </dependency>

        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-framework</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.apache.zookeeper</groupId>
                    <artifactId>zookeeper</artifactId>
                </exclusion>
            </exclusions>
        </dependency>


        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-recipes</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.apache.zookeeper</groupId>
                    <artifactId>zookeeper</artifactId>
                </exclusion>
            </exclusions>
        </dependency>


        <dependency>
            <groupId>org.apache.zookeeper</groupId>
            <artifactId>zookeeper</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.slf4j</groupId>
                    <artifactId>slf4j-log4j12</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>log4j</groupId>
                    <artifactId>log4j</artifactId>
                </exclusion>
            </exclusions>
        </dependency>


        <dependency>
            <artifactId>leaf-boot-starter</artifactId>
            <groupId>com.sankuai.inf.leaf</groupId>
            <version>1.0.1-RELEASE</version>
        </dependency>

    </dependencies>

    <dependencyManagement>

        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>


    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

我们会看到有部分依赖我们并没有指明版本,版本号是从父类中继承过来的,那么父类在哪里定义的呢?在 dependencyManagement 标签里,也就是父pom.xml 中的 :

   <dependencyManagement>

        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter</artifactId>
                <version>${spring-boot.version}</version>
            </dependency>

            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <version>${spring-boot.version}</version>
                <scope>test</scope>
                <exclusions>
                    <exclusion>
                        <groupId>org.junit.vintage</groupId>
                        <artifactId>junit-vintage-engine</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>

            ...

        </dependencies>
    </dependencyManagement>

补充

说到 dependencyManagement 不得不提到依赖有一种范围 : import ,该依赖范围存在的动机就是解决依赖单继承的问题。我们上面讲的继承关系利用 dependencyManagement 可以维护统一的依赖版本,但是这样要是给多个项目继承的话,所管理的依赖非常多,有没有一种可以众多依赖中再提取一层出来。例如我的 provider-bit 项目需要依赖父类中 dependencyManagement 中定义的 aliyun-java-sdk-core ,然后我嫌 dependencyManagement 定义的依赖太多,太乱了,于是我把 aliyun-java-sdk-core 放到了另外一个项目中去 :

com.bbk 的common 项目中

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.6.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.bbk</groupId>
    <artifactId>otherparentpom</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>otherparentpom</name>
    <description>Demo project for Spring Boot</description>

    <packaging>pom</packaging>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <!--定义在这里,当然还可以一定很多个-->
        <dependencies>
            <dependency>
                <groupId>com.aliyun</groupId>
                <artifactId>aliyun-java-sdk-core</artifactId>
                <version>4.0.6</version>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

然后在 provider-bit 中进行引用 :

    <dependencies>

        <!--看这里,我想引入的依赖-->
        <dependency>
            <groupId>com.aliyun</groupId>
            <artifactId>aliyun-java-sdk-core</artifactId>
        </dependency>

    </dependencies>

    <dependencyManagement>

        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>


            <!-- type 为 pom , scope 为 import 这就相当于多个继承了-->
            <dependency>
                <groupId>com.bbk</groupId>
                <artifactId>otherparentpom</artifactId>
                <version>0.0.1-SNAPSHOT</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

        </dependencies>
    </dependencyManagement>

总结

本节主要介绍 maven 的聚合,继承和依赖范围为 import 的引入依赖。

参考

  • https://www.infoq.cn/article/2011/01/xxb-maven-3-pom-refactoring
  • http://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html

以上是关于maven-聚合和继承的主要内容,如果未能解决你的问题,请参考以下文章

maven聚合与继承

maven 聚合与继承

Maven高级:聚合和继承

Maven继承和聚合

maven-聚合和继承

maven-聚合和继承