maven series aggregation and inheritance (and TODO)

Keywords: Maven

Chapter 8 aggregation and inheritance

Maven's aggregation feature can aggregate and build all modules of the project, while Maven's inheritance feature can help extract the same dependencies and plug-ins and other configurations of each module, simplify POM and promote the consistency of each module configuration.

8.1 mirana-dal

mirana DAL module is responsible for the persistence of mirana data, saves data in the form of json files, and supports the creation, reading, updating, deletion and other operations of accounts.

[since it is difficult to install mysql in Tencent cloud and don't want to learn more about mongo for the time being, this place directly uses the file system as the database. By the way, learn about java io. For the code, refer to the IO part of spring core]

Related classes and methods are

  1. java.util.Properties (inside the project)
  2. Knowledge of io and NiO (see NiO for more)
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">  
<parent>
        <artifactId>mirana-parent</artifactId>
        <groupId>com.ssozh</groupId>
        <version>1.0.0-SNAPSHOT</version>
    </parent>
    
    
    <build>
        <testResources>
            <testResource>
                <directory>src/test/resources</directory>
                <filtering>true</filtering>
            </testResource>
        </testResources>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>${maven.compiler.source}</source>
                    <target>${maven.compiler.target}</target>
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-resources-plugin</artifactId>
                <version>3.2.0</version>
                <configuration>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

The coordinate of this module is com. Ssozh: Mirana parent: 1.0.0-snapshot. It has the same groupId as other modules, and artifactId has the same prefix.

Generally speaking, the sub modules of a project should use the same group ID. if they are developed and published together, they should also use the same version. artifactId should also have the same prefix to facilitate other items to distinguish.

The build element contains a testResource sub element to enable resource filtering. [for unit test]. The following two plug-ins are also included. One is Maven compiler plugin, which is used to support Java 1.8 (in fact, this version is set in super POM, and this 1.8 is set in springboot start parent). In addition, Maven resources plugin is configured to process resource files using UTF-8 encoding.

8.2 polymerization

So far, mirana has implemented the createGroup method in the biz layer and the createGroup method in the dal layer. At this time, a simple requirement will be displayed naturally: we will want to build two projects at a time, rather than execute the mvn command in the directory of two modules.

In order to build multiple modules such as Mirana API, Mirana controller, Mirana common and Mirana DAL with one command, we need to create an additional module named Mirana parent, and then build all modules of the whole project through this module. Mirana parent itself, as a maven project, must have its own POM. However, as an aggregation project, its POM has special features. The content of pom.xml is as follows:

<?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.5.4</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <groupId>com.ssozh</groupId>
    <artifactId>mirana-parent</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <name>mirana-parent</name>

    <description>Demo project for Spring Boot</description>

    <packaging>pom</packaging>

    <modules>
        <module>assembly</module>
        <module>controller</module>
        <module>service</module>
        <module>biz</module>
        <module>dal</module>
        <module>common</module>
        <module>integration</module>
        <module>api</module>
        <module>starter</module>
        <module>test</module>
    </modules>

</project>

There are several special places:

  1. Packaging: pom, the packaging method of aggregation module must be pom, otherwise it cannot be built
  2. modules: the core of aggregation. Users can realize module aggregation by declaring any number of module elements in a maven project packaged as pom.
  3. Generally speaking, the directory name of the module should be consistent with its artifact ID. if it is inconsistent, you need to change < module > in the aggregate pom to the corresponding directory name.
  4. The directory structure of aggregation module and other modules does not necessarily have a parent-child relationship. Parallel directory structure can also be used. At this time, < module > should also point to the correct module directory
  5. mvn clean install process:
    1. Analyze the POM of the aggregation module and the module to be built
    2. Calculate a reactor build order
      1. This is the dependency: parent - > API - > common - > integration - > DAL - > biz - > Service - > controller - > starter - > assembly
    3. Each module is built in this order.
    4. Others: in the above process, the name of each module is output instead of artifact ID.

8.3 succession

Duplicate configurations can be extracted through inheritance, and maven also has this inheritance mechanism.

The POM as the parent module, like the POM of the aggregation module, must be the packaging type of the POM. Because the parent module is not only to help eliminate the duplication of configuration, because it does not contain project files other than POM, it does not need folders such as src/main/java.

relativePath indicates the relative path of the parent module POM. The default value is.. / pom.xml. In other cases, it needs to be written manually.

If the development team needs to move a Maven project containing parent-child relationship from the source code library, it needs to set the correct < relativepath >.

8.3.1 inheritable POM elements

From the previous section, we can see that groupId and version can be inherited. The following is a complete inheritance list:

  • groupId: project group Id, coordinate core element.
  • Version: project version, coordinates and core elements.
  • Properties: Custom Maven properties
  • dependencies: dependency configuration of the project
  • Dependency management: dependency management configuration of the project
  • repositories: repository configuration for the project
  • build: including source directory configuration, output directory configuration, plug-in configuration, plug-in management configuration, etc.
  • reporting: including report output directory configuration and report plug-in configuration of the project.
  • Description: description of the item
  • Organization: organization information of the project.
  • Inception year: the year the project was founded
  • url: the url address of the project
  • developers, contributors: information about the developer contribution value of the project
  • Distribution management: deployment configuration of the project
  • ciManagement: continuous integration system information of the project
  • scm: version control system information of the project

8.3.2 dependency management (common)

The dependency management element provided by Maven enables the child module to rely on the dependency configuration of the parent module, and ensures the flexibility of the use of child module dependencies. The dependency declaration under the dependencyManagement element does not introduce actual dependencies, but it can restrict the use of dependencies under dependencies.

	<properties>
    	<java.version>1.8</java.version>
        <mirana.parent.version>1.0.0-SNAPSHOT</mirana.parent.version>
        <mirana.api.version>1.0.0-SNAPSHOT</mirana.api.version>
        <fastjson.version>1.2.76</fastjson.version>
        <guava.version>28.2-android</guava.version>
        <mapstruct.version>1.4.2.Final</mapstruct.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>com.ssozh</groupId>
                <artifactId>mirana-api</artifactId>
                <version>${mirana.api.version}</version>
            </dependency>
            <dependency>
                <groupId>com.ssozh</groupId>
                <artifactId>mirana-starter</artifactId>
                <version>${mirana.parent.version}</version>
            </dependency>
            <!-- ................. -->
        </dependencies>
</dependencyManagement>

In this way, the relevant version and scope information is directly omitted when used in the actual test. This information can be omitted because the child project inherits the dependency management configuration in the parent project. In this way, although too many POM configurations cannot be reduced, the parent POM declares the version that can standardize and unify the project dependencies. When using dependencies, sub modules do not need to declare the version, and there will be no inconsistency in the use of dependency versions of multiple sub modules, so as to reduce the probability of dependency conflicts.

In addition, the dependency range of import described earlier. Dependencies using this range usually point to a POM to import and merge the dependency management configuration in the target POM into the dependency management element of the current POM. If you want to use the same dependency management configuration as a module in another module, in addition to copying the configuration or inheriting, you can also use import scope dependency to import this configuration.

8.3.2 plug in management

Maven provides the dependency management element to help manage dependencies, and Maven also provides the pluginManagement element to help manage plug-ins. The dependency configured in this element will not cause the actual plug-in call behavior. When the real plugin element is configured in POM and GAV matches the plug-in configured in pluginManagement, the pluginManagement configuration will affect the actual plug-in behavior.

For example, the parent project can be written as follows:

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

8.4 relationship between aggregation and inheritance

Aggregation and inheritance in multi module Maven project are actually two concepts with completely different purposes.

polymerization inherit
Concept and purpose To facilitate the rapid construction of projects To eliminate duplicate configurations
usage method < modules > to aggregate projects Subprojects < parent > and < relativepath >. Parent item < xxmanagement >

In existing practical projects, a POM is often both an aggregate POM and a parent POM. This is mainly for convenience.

8.5 agreed configuration

Maven will assume that the user's project is as follows:

  • The source directory is src/main/java/
  • The compilation output directory is target/classes
  • The packaging method is jar
  • The package output directory is target/

Although some flexibility is lost in following the agreement, users cannot arrange the directory structure at will. If you want to modify it, you can also modify it in < build >

<build>
	<sourceDirectory>src/java</sourceDirectory>
</build>

In fact, any Maven project is an inherited super POM. This is a bit similar to any java class that implicitly inherits from the Object class. In maven3, the location is $MAVEN_HOME\maven-model-builder\src\main\resources\org\apache\maven\model\pom-4.0.0.xml

See relevant codes for details:

 <build>
    <directory>${project.basedir}/target</directory>
    <outputDirectory>${project.build.directory}/classes</outputDirectory>
    <finalName>${project.artifactId}-${project.version}</finalName>
    <testOutputDirectory>${project.build.directory}/test-classes</testOutputDirectory>
    <sourceDirectory>${project.basedir}/src/main/java</sourceDirectory>
    <scriptSourceDirectory>${project.basedir}/src/main/scripts</scriptSourceDirectory>
    <testSourceDirectory>${project.basedir}/src/test/java</testSourceDirectory>
    <resources>
      <resource>
        <directory>${project.basedir}/src/main/resources</directory>
      </resource>
    </resources>
    <testResources>
      <testResource>
        <directory>${project.basedir}/src/test/resources</directory>
      </testResource>
    </testResources>
    <pluginManagement>
      <!-- NOTE: These plugins will be removed from future versions of the super POM -->
      <!-- They are kept for the moment as they are very unlikely to conflict with lifecycle mappings (MNG-4453) -->
      <plugins>
        <plugin>
          <artifactId>maven-antrun-plugin</artifactId>
          <version>1.3</version>
        </plugin>
        <plugin>
          <artifactId>maven-assembly-plugin</artifactId>
          <version>2.2-beta-5</version>
        </plugin>
        <plugin>
          <artifactId>maven-dependency-plugin</artifactId>
          <version>2.8</version>
        </plugin>
        <plugin>
          <artifactId>maven-release-plugin</artifactId>
          <version>2.5.3</version>
        </plugin>
      </plugins>
    </pluginManagement>
  </build>

8.6 reactor

In a multi module Maven project, reactor refers to a building structure composed of all components. For a single module project, the reactor is the module itself. For multiple modules, the reactor includes the inheritance and dependency relationship between modules, so as to automatically calculate the reasonable module construction order.

8.6.1 reactor construction sequence

The dependency relationship between modules will construct the reactor into A directed acyclic graph (DAG). Each module is the node of the graph, and the dependency relationship constitutes A directed edge. This diagram does not allow loops. Therefore, when module A depends on module B and B depends on A, Maven will report an error.

8.6.2 tailoring reactor

Sometimes, users will want to build only some modules in the complete reactor. In other words, users need to tailor the reactor in real time.

maven provides many command-line options to support reactor clipping. You can see these options by outputting mvn -h:

  • -am: -- the dependent module of the module listed in the also make receipt
  • -amd: -- alse make dependencies also builds modules that depend on the listed modules
  • -pl: -- projects < args > build the specified modules, separated by commas
  • -rf: - resume from < args > replies from the specified module

Specific examples:

# Build a complete reactor
mvn clean install
# Use the - pl option to specify how many modules to build
mvn clean install -pl mirana-dal, mirana-biz
## Use the - am option to take the postgraduate entrance examination and build the dependent modules of the listed modules at the same time
mvn clean install -pl mirana-dal -am
## Use the - amd option to take the postgraduate entrance examination and build modules that depend on the listed modules at the same time
mvn clean install -pl mirana-dal -amd
## Use the - rf option to specify which module to build from based on the complete reactor sequence. For example:
mvn clean install -rf mirana-dal

In the development process, the flexible application of the above four parameters can help us skip modules that do not need to be built, so as to speed up the construction. [at present] we haven't used these in our actual project

8.7 summary

This chapter introduces the two features of aggregation and inheritance, then introduces the optimization configuration, and finally introduces the reactor and related command parameters for tailoring the reactor.

other

  1. junit annotation

    1. @Before can be used to execute the method before executing the test case. The IoC container that can be used to initialize the spring framework.
    2. @The Test annotation indicates the method to be tested.
  2. How is the Model.class in Maven generated through maven.mdo in Maven model?

  3. Since Maven does not allow circular dependency, what is the circular dependency through @ Resource in spring?

Posted by ah66533 on Sun, 07 Nov 2021 10:04:21 -0800