Location>code7788 >text

[This is probably the best Spring tutorial!] Maven's Module Management - How to Split Large Projects and Ensure Code Profile with Parent Inheritance

Popularity:367 ℃/2024-11-13 08:56:07

Formulation of the problem

In software development, in order to reduce the complexity of the software, we will not put all the functions are stuffed into a module, stuffed in a module for the management of the software is undoubtedly extremely difficult and complex. So splitting a project into modules is a good way to do it.

                        ┌ ─ ─ ─ ─ ─ ─ ┐
                          ┌─────────┐
                        │ │Module A │ │
                          └─────────┘
┌──────────────┐ split  │ ┌─────────┐ │
│Single Project│───────▶  │Module B │
└──────────────┘        │ └─────────┘ │
                          ┌─────────┐
                        │ │Module C │ │
                          └─────────┘
                        └ ─ ─ ─ ─ ─ ─ ┘

For the Maven project, it turned out to be a big one:

single-project
├── 
└── src

It can now be split into 3 modules:

multiple-projects
├── module-a
│   ├── 
│   └── src
├── module-b
│   ├── 
│   └── src
└── module-c
    ├── 
    └── src

What we can see is that each module has its own, and then module A'sIt's like this:

<project xmlns="/POM/4.0.0"
    xmlns:xsi="http:///2001/XMLSchema-instance"
    xsi:schemaLocation="/POM/4.0.0 /xsd/maven-4.0.">
    <modelVersion>4.0.0</modelVersion>

    <groupId></groupId>
    <artifactId>module-a</artifactId>
    <version>1.0</version>
    <packaging>jar</packaging>

    <name>module-a</name>

    <properties>
        <>UTF-8</>
        <>UTF-8</>
        <>11</>
        <>11</>
        <>11</>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.28</version>
        </dependency>
        <dependency>
            <groupId></groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.2.3</version>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId></groupId>
            <artifactId>junit-jupiter-engine</artifactId>
            <version>5.5.2</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>

After that B'sIt's pretty much the same thing, just put the<artifactId>module-a</artifactId> cap (a poem)<name>module-a</name> Just change it to your own. This time we will find a very troublesome thing, we have a lot of places are the same, but each module of the pom need us to repeat the declaration out, that we can not use like an object like inheritance, so that there is no need to repeat the declaration of it?Maven undoubtedly has such a function!

Problem solving

simplified structure

Let's now see how the simplified module structure looks like

multiple-project
├── 
├── parent
│   └── 
├── module-a
│   ├── 
│   └── src
├── module-b
│   ├── 
│   └── src
└── module-c
    ├── 
    └── src

In contrast, the root directory has an extra pom, and then an extra "module" parent, which has no code src, just a bare pom.

After seeing the comparisons we'll talk one by one about how the modifications were made and what the structure looks like

Modification of the rules

parent

Let's first look at what's going on with the pom inside parent

<project xmlns="/POM/4.0.0"
    xmlns:xsi="http:///2001/XMLSchema-instance"
    xsi:schemaLocation="/POM/4.0.0 /xsd/maven-4.0.">
    <modelVersion>4.0.0</modelVersion>

    <groupId></groupId>
    <artifactId>parent</artifactId>
    <version>1.0</version>
    <packaging>pom</packaging>

    <name>parent</name>

    <properties>
        <>UTF-8</>
        <>UTF-8</>
        <>11</>
        <>11</>
        <>11</>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.28</version>
        </dependency>
        <dependency>
            <groupId></groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.2.3</version>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId></groupId>
            <artifactId>junit-jupiter-engine</artifactId>
            <version>5.5.2</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>

What we can find is that the modifications to the previous module A are not really that much, the modifications are respectively<artifactId>parent</artifactId> <packaging>pom</packaging> <name>parent</name>

Here we focus on<packaging>pom</packaging>First of all, let's understand<packaging>What this label represents.

<packaging>This tag indicates the way the package is packaged, and the common values arejar(Java library),war(Web application),pom(parent project), etc. This placeparent(used form a nominal expression)packagingset topom, because it does not generate any executable JAR files and only provides configuration and dependency management.

Simplified ideas for other modules

After looking at the parent's code we'll slowly work our way through the simplification.

Encoding and java version configuration

The brunt of this is undoubtedly this part, this place module AB are required and are the same, then this element is inheritable, that is, theIt can be omitted.

<properties>
        <>UTF-8</>
        <>UTF-8</>
        <>11</>
        <>11</>
        <>11</>
    </properties>
Public dependencies

Next are dependencies that are required by both ABs such asslf4j-apilogback-classiccap (a poem)junit-jupiter-engineand the setting of scopes

<dependencies>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.28</version>
        </dependency>
        <dependency>
            <groupId></groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.2.3</version>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId></groupId>
            <artifactId>junit-jupiter-engine</artifactId>
            <version>5.5.2</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

Modified pom for module A

Let's take a look at the modified pom of module A again.

<project xmlns="/POM/4.0.0"
    xmlns:xsi="http:///2001/XMLSchema-instance"
    xsi:schemaLocation="/POM/4.0.0 /xsd/maven-4.0.">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId></groupId>
        <artifactId>parent</artifactId>
        <version>1.0</version>
        <relativePath>../parent/</relativePath>
    </parent>

    <artifactId>module-a</artifactId>
    <packaging>jar</packaging>
    <name>module-a</name>
</project>

I have to say that with parent, the whole module is clean and simple

After setting up theparentmodule, we only need to refer to theparentActs as a parent module for other modules.

first by<parent>label citationparentmodule (in software)

    <parent>
        <groupId></groupId>
        <artifactId>parent</artifactId>
        <version>1.0</version>
        <relativePath>../parent/</relativePath>
    </parent>

With this it is equivalent to inheriting the elements inside the parent.

After that, we import our own unique elements and we're basically done configuring the module.

<artifactId>module-a</artifactId>
<packaging>jar</packaging>
<name>module-a</name>

predecessorparentAfter the module, module A and module B of theThe documentation has been greatly simplified. All public configuration items, such asUTF-8coding, Java compilation versions, and dependency libraries for logging and testing, have all been added to theparentThe configuration is configured in the In this way, Module A and Module B only need to retain unique content, simplifying configuration and reducing maintenance costs.

cross reference

If module A needs to refer to the code of module B, you can add a reference to it in module A's<dependencies>Add a dependency on module B in the following:

<dependencies>
    <dependency>
        <groupId></groupId>
        <artifactId>module-b</artifactId>
        <version>1.0</version>
    </dependency>
</dependencies>

With this configuration, Maven will automatically fetch the JAR file generated by Module B when building Module A, allowing Module A to use the code and functionality in Module B.

Configuration of the root pom

At the end of the day, the idea behind configuring our final root pom is to accomplish a unified compilation of all projects:

<project xmlns="/POM/4.0.0"
    xmlns:xsi="http:///2001/XMLSchema-instance"
    xsi:schemaLocation="/POM/4.0.0 /maven-v4_0_0.xsd">

    <modelVersion>4.0.0</modelVersion>
    <groupId></groupId>
    <artifactId>build</artifactId>
    <version>1.0</version>
    <packaging>pom</packaging>
    <name>build</name>

    <modules>
        <module>parent</module>
        <module>module-a</module>
        <module>module-b</module>
        <module>module-c</module>
    </modules>
</project>

Thus, in the root directory, executemvn clean packageWhen Maven is used, it is based on the root directory'sFind out what's included inparentTotal 4 within<module>, compiled all at once.

This is probably the best Spring tutorial!

Thank you for seeing this.This is probably the best Spring tutorial series More articles can be viewed hereThis is probably the best Spring tutorial! Getting Started with Spring even without the basics, still continuously updated.I also updated the most detailed Spring tutorials at Lychee!