"Maven combat" learning summary (six)-multi-project construction problem solution: aggregation and inheritance

Multi-project build problem

       With the development of software, the software itself becomes more and more complex. We often divide a large project into several modules for development. If we use Maven to build, the divided modules are actually multiple different Maven. project.

Under such circumstances, the construction of multi-module projects faces two problems:

       1. When there are many divided modules, we need to execute the build command separately for each project, which undoubtedly reduces the efficiency of the build;

       2. There are many common configurations in the configuration of multi-project construction. For example, the groupId and version of the project need to be consistent because of the dependency relationship. Many projects will introduce common dependencies, which is not conducive to maintenance.


In order to solve the above two problems, Maven provides two features of aggregation and inheritance.


polymerization

       The role of aggregation is that we can build two or more projects by executing a command. The project executed by the command should also be an independent additional project. The POM configuration of the aggregation project is as follows:

    <artifactId>pro-test-aggregator</artifactId>
    <groupId>com.cic</groupId>
    <version>1.0-SNAPSHOT</version>
    <modelVersion>4.0.0</modelVersion>
    <packaging>pom</packaging>
    <modules>
        <module>pro-test1</module>
        <module>pro-test2</module>
    </modules>


       In this way, when we run the Maven build command under the pro-test-aggregator project, Maven will parse this configuration and calculate the reactor build order (Reactor Build Order): a build structure composed of all modules, built in the order of declaration, encountered If there is a dependent module, first build the module it depends on. Pay attention to avoid circular dependencies between projects, otherwise it will build errors.

       Finally, a directional acyclic graph reactor is parsed for construction. Of course, we can also control which projects are built and which projects are not built through the command line. This feature is called a tailored reactor.

      

inherit

       Similar to inheritance between classes, Maven's feature of repetitive configuration is also called inheritance. Through inheritance, we can implement one declaration and multiple references. The existing parent project is defined as follows:

    <groupId>com.cic</groupId>
    <artifactId>parent</artifactId>
    <packaging>pom</packaging>
    <name>parent</name>
    <version>1.0-SNAPSHOT</version>


        It can be seen that the life of the parent project is not much different from other projects, but the packaging method is similar to the aggregation project, which is also "pom".

        Sub-projects are configured as follows to achieve inheritance

    <parent>
        <groupId>com.cic</groupId>
        <artifactId>parent</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <artifactId>pro-test1</artifactId>
    <name>pro-test1</name>

       The parent node configures the parent project information. There is a <relativePath> child node, which can locate the pom.xml of the parent project. If this item is not configured, the default is <relativePath> ../ pom.xml </ relativePath>. File, it will go to the local warehouse to find and locate. The child project does not declare groupId and version, and can inherit from the parent project by default. If the elements of the child project are different from the parent project, the declaration can be displayed completely.

        There are many inheritable POM elements, including: groupId, version, properties (custom Maven attributes), dependencies, dependencyManagement, repository and other project information. It is worth mentioning that all project Pom configurations inherit from the super POM provided by Maven, which also explains that Maven projects can be built with very few configurations.


Dependency management

       We can use the dependencies node to define the dependent projects uniformly, but there is a problem here: if the dependencies are defined in the parent project through dependencies, the subproject will inherit all the dependencies of the parent project, that is to say, it may introduce projects that the subproject does not depend on Instead, there is a chaos. To solve this problem, we can use the <dependencyManagement> node to define the dependency in the parent project. The child project will not directly introduce the dependency after inheriting the parent project, but need to show it again to indicate what it is. Dependence on inheritance. The specific configuration is as follows:

       parent project

<dependencyManagement>
        <dependencies>
            <!-- Common libs -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-core</artifactId>
                <version>${spring.bom.version}</version>
                <exclusions>
                    <exclusion>
                        <artifactId>commons-logging</artifactId>
                        <groupId>commons-logging</groupId>
                    </exclusion>
                </exclusions>
            </dependency>

            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-framework-bom</artifactId>
                <version>${spring.bom.version}</version>
                <type>pom</type>
                <scope>import</scope>
                <exclusions>
                    <exclusion>
                        <artifactId>commons-logging</artifactId>
                        <groupId>commons-logging</groupId>
                    </exclusion>
                </exclusions>
            </dependency>
	</dependencies>
</dependencyManagement>
        The sub-project configuration is as follows

    <dependencies>
        <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-test</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
        </dependency>
    </dependencies>

       With this configuration method, although there is not much reduction in configuration, the dependent versions can be managed uniformly in the parent project, and the versions of each dependent package can be uniformly defined under the <properties> node.

       Attentive readers found that when we introduced the <spring-framework-bom> project in the parent project, the <scope> node attribute is configured with an " import " value, which means that the content of the <dependencyManagement> node in the target dependency is imported and merged into the current Under the project, we can view the Pom file of this dependent project, which defines a series of modules related to the Spring project, and therefore simplifies the dependency configuration of the current project.


In the same way, corresponding to the dependency, the management of the plug-in also has a similar configuration node <pluginManagement>, the effect of which is similar to the dependency management, and will not be repeated here.


to sum up

        This article introduces the two features of Maven to deal with multi-project problems, the proposed aggregation and inheritance, I believe that with these two points of learning, we can make good use of these two configurations when dividing and configuring multiple modules At the same time, we can also understand the realization mechanism of Maven's core design concept "convention is better than configuration".

Published 159 original articles · praised 225 · 210,000 views

Guess you like

Origin blog.csdn.net/lyg673770712/article/details/51029719