After reading "Maven in Action"

Table of contents

1. Some thoughts

1. Why is the Java project that is usually written also called the Maven project?

That's because the projects that are usually written are written according to the Maven writing specification, and the directory structure and pom.xml are all in accordance with the maven configuration requirements and add corresponding values

2. Why does the usual Java project directory look like this? Can the directory structure be changed?

Let's take a look at the modules RuoYiin the project ruoyi-admin, as follows:

insert image description here

Everyone should have written java code. Generally, the main code is placed src/main/javaunder the directory, the main configuration file is placed src/main/resourcesunder the directory, the test code is placed src/test/javaunder the directory, the test configuration file is placed src/test/resourcesunder the directory, and then pom.xmlthe files are placed under the module. , which is all stipulated by maven in the super pom.xml (similar to the super class of all classes is Object, that is, all pom.xml will inherit the super pom)

Then let's look for the regulations in the maven super pom.xml, find maven安装目录it below lib目录, and find it inside maven-model-builderXXX.jar(where XXX is the installed maven version, for example, my maven version is 3.5.4, then the jar package I need to find is maven-model-builder-3.5.4.jar), then we open the jar package through the decompilation tool, then find the org.apache.maven.modeldirectory, and then open the pom-4.0.0.xml in the directory, then we will see the following content, where ${project.basedir}is the directory of the current module:

insert image description here

Description: A jar package decompilation tool is recommended: jd-gui.ext

When maven executes related commands, for example, mvn clean packageit will use the above directories for related work, so we must let maven know where these directories are. If we want to change the main code directory, main resource directory, test code directory, test The location of the resource directory, then we need to imitate the writing of the super pom and specify it in the pom.xml file of our module, so that maven knows where the maven it needs is.

For some old projects, they may not be managed by maven. Now we need to change the project to be managed by maven, but the code of this old project may be under the sourcedirectory instead of src/main/javabelow. At this time, we need to change the main code in the module The location of the directory, this situation has been encountered in our company's previous old projects changing maven code, as follows:

insert image description here

3. For the Maven project, what can Maven do for us?

Maven is a cross-platform project management tool, mainly used in project information management, project construction, and dependency management.

  • Cross-platform: Maven can be installed on the Windows platform (used during code development) or on the Linux platform (use Jenkins to operate Maven to directly compile and package the code)
  • projectProject information management: Many project information elements can be placed under pom.xml elements, such as:
    • name: name
    • description: description
    • organization: the organization to which it belongs
    • licenses (collection) "license: license
    • mailingLists (collection) "mailingList: mailing list
    • developers (collection) "developer: developer
    • Contributors (collection) "contributor: Contributor
    • issueManagement: issue tracking system
    • ciManagement: continuous tracking system
    • scm: version control system
      insert image description here
  • Project construction: maven has a lot of commands, the most commonly used ones are clean, compile, package, install, test, among which the project is packaged and built withmvn clean package
  • Dependency management: Many dependencies are placed in pom.xml, and maven can introduce dependencies, exclude dependencies, inherit dependencies, set dependency ranges, etc.

4. Why do you need a Maven private server, can you not do it?

The company did not build a maven private server before, and every new colleague who joins the job will receive a large tomcat. The jar package in this tomcat is very complete, and basically all jar packages are used. Although there is no problem in normal development, once it needs to be introduced New jar packages, some jar packages need to be excluded, and project jar packages developed by other colleagues need to be used. This process is very uncomfortable, but after having a maven private server, this kind of thing can be changed. Maven can help us To perform dependency management, and we can also send the project jar package developed by ourselves to the maven warehouse, and then let other colleagues introduce

Some friends will also say that Alibaba Cloud's maven warehouse should be very fast now, so why do we still build a maven private server, which consumes bandwidth and storage space. Have you ever thought about these scenarios, the company's internal infrastructure will definitely generate some jar packages, and these jar packages must not be sent to the public network, so a maven private server is needed to store the jar packages. Of course, the role of maven private server is not only that, for example, it can also save the company's network bandwidth, ensure the stability of maven warehouse access, etc.

5. Why must execute mvn clean before executing mvn package?

This involves the life cycle management of maven. In fact, the clean and package commands are all stage names in the life cycle. In fact, there are three sets of life cycles in maven, namely clean, default, and site, among which:

  • Clean life cycle:
    insert image description here
  • default life cycle:
    insert image description here
    insert image description here
    insert image description here
  • Site life cycle:
    insert image description here

It can be seen from the above clean阶段that in clean生命周期, and package阶段indefault生命周期

First of all, let me explain two points. These three life cycles have no linkage relationship. For each stage in the life cycle, when the later stage is executed, the previous stage must be executed first.

clean阶段Since we need to delete first target目录, and then execute the latest code package阶段(because it compile阶段is in package阶段the front, package阶段it will definitely be executed when executing compile阶段), so execute packagethe command to execute cleanthe command first

6. Why is the maven-compiler-plugin plug-in generally configured in pom.xml, and the values ​​of source and target are set?

In the module, pom.xmlwe generally see such plug-in settings, as follows:

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.1</version>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
                <encoding>UTF-8</encoding>
            </configuration>
        </plugin>
    </plugins>
</build>

It is mentioned on page P33 of "Maven Combat":

This is a problem Maven beginners often encounter. Due to historical reasons, one of Maven's core plugins, the compiler plugin, supports compiling Java 1.3 by default, because it needs to be configured to support other Java versions

Since there are expressions written in my code lamda, this is a feature of java8, so the compiler must support the java8 version, because the relevant attribute information is added in the plug-in

In fact, this is related to the super Pom, but I see that the default version of the compiler plugin is not defined in the super Pom in Maven version 3.5.4, so if we do not define the version of the compiler plugin, the latest stable version will be used, so You don’t have to worry about this problem, it mainly depends on the version of maven, so if the author may worry about problems due to different versions when writing the project, he directly and explicitly states the version of the compiler plug-in to avoid problems

7. How to configure pom.xml and settings.xml to push the project into a jar package to the maven private server, and download dependent jar packages from the maven private server?

This requires related configuration of various addresses in pom.xml and settings.xml, and TODO will be supplemented later

2. Small knowledge points

1. The relationship between gav and directories in pom.xml

  • gav in pom.xml
    • groupId: Define which group the project belongs to. This group is often associated with the organization and company where the project is located. Generally, it is the reverse order of the company domain name + the project name, such as: , or it can be just the reverse order of the com.atguigu.netilercompany domain name, such as:com.ruoyi
    • artifactId: Define the unique ID of the current Maven project in the group, usually the subproject (module) name, for example:kms-wiki
    • version: defines the subproject (module) version
  • Directory: Since the structure of the main code directory and the test code directory are basically similar, take the main code directory as an example, under the src/main/javadirectory is groupId/artifactId(Note: 1, replace . in groupId with /; 2, artifactId can be changed, for example, if One of the modules is ruoyi-system, and the directory is: src/main/ava/com/ruoyi/system; For example, in our example below, just kms-wikireplace it with ) in the directory kmswiki), and then you can write code in the next directory, such as:src/main/java/com/atguigu/netiler/kmswiki

2. The location of the super Pom

The status of the super Pom is equivalent to the Object superclass in java programming, so the business code pom.xml will inherit the configuration in the super Pom, and we can also rewrite the relevant configuration in the pom.xml in the business code to configure the super Pom Configuration, where the super Pom is located in Maven安装位置" lib" , my maven version is 3.5.4, and the content of pom-4.0.0.xml is as follows:maven-model-builder-XXX.jarorg.apache.maven.model.pom-4.0.0.xml

<?xml version="1.0" encoding="UTF-8"?>

<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License.  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied.  See the License for the
specific language governing permissions and limitations
under the License.
-->

<!-- START SNIPPET: superpom -->
<project>
  <modelVersion>4.0.0</modelVersion>

  <repositories>
    <repository>
      <id>central</id>
      <name>Central Repository</name>
      <url>https://repo.maven.apache.org/maven2</url>
      <layout>default</layout>
      <snapshots>
        <enabled>false</enabled>
      </snapshots>
    </repository>
  </repositories>

  <pluginRepositories>
    <pluginRepository>
      <id>central</id>
      <name>Central Repository</name>
      <url>https://repo.maven.apache.org/maven2</url>
      <layout>default</layout>
      <snapshots>
        <enabled>false</enabled>
      </snapshots>
      <releases>
        <updatePolicy>never</updatePolicy>
      </releases>
    </pluginRepository>
  </pluginRepositories>

  <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>

  <reporting>
    <outputDirectory>${project.build.directory}/site</outputDirectory>
  </reporting>

  <profiles>
    <!-- NOTE: The release profile will be removed from future versions of the super POM -->
    <profile>
      <id>release-profile</id>

      <activation>
        <property>
          <name>performRelease</name>
          <value>true</value>
        </property>
      </activation>

      <build>
        <plugins>
          <plugin>
            <inherited>true</inherited>
            <artifactId>maven-source-plugin</artifactId>
            <executions>
              <execution>
                <id>attach-sources</id>
                <goals>
                  <goal>jar-no-fork</goal>
                </goals>
              </execution>
            </executions>
          </plugin>
          <plugin>
            <inherited>true</inherited>
            <artifactId>maven-javadoc-plugin</artifactId>
            <executions>
              <execution>
                <id>attach-javadocs</id>
                <goals>
                  <goal>jar</goal>
                </goals>
              </execution>
            </executions>
          </plugin>
          <plugin>
            <inherited>true</inherited>
            <artifactId>maven-deploy-plugin</artifactId>
            <configuration>
              <updateReleaseInfo>true</updateReleaseInfo>
            </configuration>
          </plugin>
        </plugins>
      </build>
    </profile>
  </profiles>

</project>
<!-- END SNIPPET: superpom -->

3. Maven Private Server—Nexus

1. The reason for putting it here

Before I really introduce the knowledge points, I would like to talk about the situation of Maven’s private server Nexus, because the places related to dependent upload and download in pom.xml and settings.xml are related to private servers. Although there are many kinds of Maven private servers to choose from, the most popular one is Nexus

2. The role of maven private server

  • Reduce central warehouse load
  • Save Internet bandwidth
  • Speed ​​up Maven builds
  • Deploy and build yourself

3. Build Nexus in k8s

Directly check the k8s cloud native environment construction notes安装nexus

4. Host warehouse, proxy warehouse, warehouse group

These are all warehouses, but they are used for different purposes.

  • Host warehouse: used to place the company's own components (both business projects and plug-ins are components), divided into Release (used to deploy release version components) and Snapshot type (used to deploy snapshot version components)
  • Proxy warehouse: used to place components in remote warehouses, such as components downloaded from Alibaba Cloud Central Warehouse
  • Warehouse group: Do not place any components. It is used to load the host warehouse and proxy warehouse. It is similar to the role of nginx. In the future, download requests will be assigned to other warehouses, and the warehouse group will be used as a portal.

The content of the book is posted below for a detailed explanation:

insert image description here

5. Create a host warehouse

First, you need to click the Create Warehouse button, as shown below:

insert image description here

Then select the host warehouse type, as follows:

insert image description here

Then select and enter the corresponding parameters. Version policyGenerally speaking, the jar package of the Snapshot version will be separated from the storage location of the jar package of the official release version, so we need two host warehouses, one of the type Version policyand Releasethe Snapshotother, using To store the corresponding type of jar package, the description information is as follows:

insert image description here
insert image description here

I used two warehouses to store the components of the release version and the components of the snapshot version. They are test-dev and test-snapshot respectively, as follows:

insert image description here

6. Create a proxy warehouse

First, you need to click the Create Warehouse button, as shown below:

insert image description here

Then select the agent warehouse type, as follows:

insert image description here

In China, Alibaba Cloud Central Warehouse (address: http://maven.aliyun.com/nexus/content/groups/public) is still very fast, so I choose Alibaba Cloud Central Warehouse as the proxy warehouse, as follows:

insert image description here

Currently I have set up a proxy repository test-alias follows:

insert image description here

7. Create warehouse group

First, you need to click the Create Warehouse button, as shown below:

insert image description here

Then select the warehouse group type, as follows:

insert image description here

The warehouse group is similar to the role of nginx, which can wrap the host warehouse and agent warehouse as the unified entrance of the warehouse, as follows:

insert image description here
insert image description here

8. Warehouse link

insert image description here

9. Nexus tutorial

Complete teaching: nexus builds maven private server

四、settings.xml

1. The reason for putting it here

pom.xml contains more information, and settings.xml is relatively simple, so let's talk about settings.xml first, and then when talking about pom.xml, some content can be explained in conjunction with settings.xml

2. Repositories and pluginRepositories in pom.xml, then repositories and pluginRepositories in settings.xml, then repositories and pluginRepositories in super pom, and then the image in settings.xml, which one will take effect?

(1) Configuration methods of repositories and pluginRepositories in pom.xml

The repositories element is the connection information of the common warehouse (business code jar package), and the pluginRepositories element is the connection information of the plug-in warehouse (maven plugin jar package). The details will be explained in detail below

insert image description here

(2) Configuration methods of repositories and pluginRepositories in settings.xml

The repositories element is the connection information of the ordinary warehouse (business code jar package), and the pluginRepositories element is the connection information of the plug-in warehouse (maven plugin jar package), and then activate the configuration of the profile element through the activeProfile element below. The details are as follows will explain in detail

insert image description here

insert image description here
insert image description here

(3) Configuration methods of repositories and pluginRepositories in super pom

Find the super Pom: find maven安装目录it below lib目录, find it inside maven-model-builderXXX.jar(where XXX is the installed maven version, for example, my maven version is 3.5.4, then the jar package I need to find is maven-model-builder-3.5.4.jar) , and then we open the jar package through the decompilation tool, then find org.apache.maven.modelthe directory, and then open the pom-4.0.0.xml in the directory, then we will see the super Pom, where the super Pom is similar to the Object class in java programming , so everything in the super pom other pom.xml will inherit

insert image description here

(4) Mirror configuration method in settings.xml

In the above two methods, whether it is a repository element or a pluginRepository element, there is an id element corresponding to it. If the value of the id element can match the value in the mirrorOf element, the request will be forwarded to the url referred to by the mirror image. Address to perform jar package download work. For example, if it is configured in the mirrorOf element *, all download requests will go here, and other configuration methods are equivalent comparisons. As for the details, it will be explained in detail below

insert image description here
insert image description here

(5) Effective principle

  • Find a suitable warehouse:
    When downloading dependencies , settings.xmlthe image information in will not be involved first, that is, the configuration information of ordinary warehouses and plug-in warehouses in , , and will be involved . The order of priority from large to small is: > pom.xml>settings.xml超级Pompom.xmlsettings.xml超级Pom

  • After selecting the warehouse, it is necessary to discuss whether settings.xmlto configure mirror information in

    • There is matching image information in settings.xml: then it depends on whether the image information can be configured with warehouse information. In fact, it depends on whether the id element value of the warehouse matches the mirror mirrorOfelement. If they do not match, it means that there is no available image information. For example, if it is configured in the mirrorOf element *, all download requests will go here, and other configuration methods are equivalent comparisons. For matching image information, you need to find the user information corresponding to the id element value in the servers element according to the id value in the image to log in to obtain the relevant jar package. What is the url configuration for the common warehouse and the plug-in warehouse configuration? it doesn't matter anymore
    • There is no matching image information in settings.xml: then you need to find the user information corresponding to the id value in the servers element according to the id value configured in your own to obtain the relevant jar package
  • If the ip of the selected remote warehouse cannot be accessed, then it is the turn of the remote warehouse with other configuration methods, otherwise the remote warehouse is still downloaded, even if the download result is problematic

  • For the common warehouse and the plug-in warehouse, if the id element value is the same, the coverage effect will be generated according to the priority rules. For example, the id element values ​​​​of the normal warehouse and the plug-in warehouse configured in the super Pom are both central, so I set it in settings. Replace the id element value of the common warehouse and the plug-in warehouse in xml with central, then the warehouse information in settings.xml will overwrite the warehouse information of the central warehouse

A picture is worth a thousand words. I will use a flow chart to show you a download process of the common business code jar package. Of course, the download process of the plug-in code jar package is also the same, so I won’t go into details, as follows:

insert image description here

3. How to configure the repositories and pluginRepositories in settings.xml to control the download of components?

Whether it is a normal Maven project or a Maven plug-in project, which includes release version and snapshot version construction, then when downloading components, it is necessary to control whether the component can be downloaded, the frequency of checking and updating components, and the strategy of checking and verifying

  • enabled: Whether to enable the support for downloading components, it will be downloaded only if it is enabled, otherwise it will not be downloaded
  • updatePolicy: Configure the frequency for Maven to check for updates from the remote warehouse. The default value is daily, which means that Maven checks once a day. The optional values ​​​​are as follows
    • daily: check once a day, which is also the default
    • always: check for updates every build
    • interval: X: Check for updates every X minutes (X is any integer)
    • never: Never check for updates.
      The above optional values ​​need to be adjusted according to the actual situation. Generally, they are often used in downloading snapshot version components. For example, I can’t connect to the company’s intranet now, so I can only change the update strategy to never, otherwise Will affect the project build.
      In the past, some colleagues in the company did not know much about the use of component update strategies in Maven. There was a case where the latest snapshot version of the component could not be obtained by calling the maven build project in Jenkins. It also happened that colleague A published the latest snapshot version to the Maven warehouse, and then Colleague B has to ask colleague B which snapshot version component is released when building, and then colleague A deletes the snapshot version in the local warehouse, and then pulls the latest snapshot version component after rebuilding the project. In fact, these situations are not correct. Understand how to use Maven
  • checksumPolicy: It is used to verify the files in Maven’s local warehouse. Generally, it can be set to ignore, so as not to affect our normal use. The information in the book is as follows:
    insert image description here
  • Example:
    Below is an example of what I use in settings.xml
    insert image description here

4. Settings.xml location description

The book "Maven Combat" advocates configuring user-wide settings.xml and local Maven warehouses, but I like to configure global-wide settings.xml and local Maven warehouses, because my computer is only used by me, and the settings. It is easier for me to find the xml and local Maven warehouse in an exact location, otherwise I have to go to the user directory of the C drive to find it, which is too troublesome!

I usually install Maven in a certain drive letter, and then confthe settings.xml in the directory of the maven installation location is the global configuration file, for example:

insert image description here

5. Relevant knowledge points

6. Explanation of the role of elements

settings.xml element reference:
insert image description here

(1)localRepository

  • Meaning: the location of the local warehouse

  • Default value: ${user.home}/.m2/repository; Note: The front ${user.home}represents the user directory, which is different under windows and linux. In addition, for linux, the .directory starting with is a hidden directory, so you need ls -aa command to see the hidden directory

  • Example windows configuration:<localRepository>C:\software\MAVEN\apache-maven-3.5.4\mavenRepository</localRepository>

  • Linux configuration example:<localRepository>/var/jenkins_home/maven_repository</localRepository>

(2)proxies

It is used to set the HTTP proxy. The specific function is that when you cannot directly access the Maven private server, but need to access the Maven private server through a network proxy, or even a network proxy with a username and password to log in, then you need to use this piece of content. , but our company is developing on the intranet but has not encountered such a situation so far, so I will not introduce it here. Interested friends can go to: 《Maven实战》P17——This 2.4 设置HTTP代理section

(3)servers

  • Meaning: Configure the user name and password for logging in to the Maven private server, which is used to access pom.xml, settings.xml, normal warehouses, plug-in warehouses, mirrors, host warehouses (upload jar packages), and snapshot warehouses (upload jar packages) in pom.xml, settings.xml, and super pom maven private server use

  • Usage: You can server》idconfigure the id value in , as long as the id in pom. If the id value corresponds, you can use the username and password values ​​to access the Maven private server, for example:

    • The warehouse id in pom.xml matches the id in the server:
      insert image description here

    • The warehouse id in settings.xml matches the id in the server:
      insert image description here

    • The mirror id in settings.xml matches the id in the server:insert image description here

    • The warehouse id in pom.xml matches the id in the server:insert image description here

  • Value meaning: The above has basically introduced the meaning of the id value, and the following introduces the values ​​of the other two parameters, which are username and password. These two parameters are the user login information of Maven private servers (such as Nexus)

  • Example values:

<servers>
	<server>
	  <id>admin</id>
	  <username>admin</username>
	  <password>admin123456</password>
	</server>
	<server>
	  <id>central</id>
	  <username>admin</username>
	  <password>admin123456</password>
	</server>
</servers>

(4)mirrors

  • Meaning: In the book "Maven Combat", it is mentioned that the scope of the mirror is wider than that of the warehouse. If the warehouse and the mirror can match, it will find the appropriate user information according to the mirror id, and then access Maven with the mirror url value Private server, and then upload the jar package to the Maven warehouse, or download the jar package from the Maven warehouse
  • How to match the warehouse and the mirror: If the id value of the warehouse can match the mirrorOf value of the mirror, it means that the match is successful. If mirrorOf is a wildcard *, it can match all warehouses; otherwise, it needs to be exactly the same to match.
  • Example values:
<mirrors>
	<mirror>
	  <id>admin</id>  
	  <url>http://192.168.139.133:31743/repository/test-public/</url>   
	  <mirrorOf>*</mirrorOf>    
	</mirror>
</mirrors>

(5)profiles

  • Meaning: add warehouse information + configuration information

  • Where to use: pom.xml, settings.xml

  • Which attributes can theoretically be used:
    insert image description here

  • What properties can be used in real situations:
    insert image description here
    Reason: To avoid problems after the project is moved to other places, so Maven does not allow users to declare dependencies or plug-ins in the profile in settings.xml, so in fact only the above three can be used in settings.xml elements

  • Example of use:
    Explanation: This is the maven information configured within our company. The left side is settings.xml, where the warehouse configuration information is used to download the jar package (common business jar package + Maven plug-in jar package), and the attribute configuration information is It is used for the pom.xml on the right, which is for uploading the jar package (common business jar package + Maven plug-in jar package). The
    insert image description here
    configuration information for downloading the plug-in jar package is not mentioned above. Here is an example of Nexus built by myself:
    insert image description here

  • activation method

    • Command line activation: mvn clean install -PXXX,XXX, where XXX refers to the id in the profile, multiple profiles can be activated at one time
    • The settings file is explicitly activated: just configure it directly, as follows:
      insert image description here
    • System Property Activation
      is better explained by directly quoting from the book, as follows:
      insert image description here
      insert image description here
    • OS Environment Activation
      is better explained by directly quoting from the book, as follows:
      insert image description here
      insert image description here
    • The presence or absence of the file
      is better explained by directly quoting from the book, as follows:
      insert image description here
    • Activated by default:
      It is better to explain the content directly from the book, as follows:insert image description here
      insert image description here

Five, pom.xml

1. The reason for putting it here

The settings.xml has been briefly introduced above. In fact, the content in settings.xml is relatively small. After all, its main function is to set the local warehouse localRepository, configure the user information server for logging in to Maven private servers, configure the mirror mirror, configure the warehouse and Configure information profile, configure activeProfiles to activate profile;

Simply done, then you need to pay attention to the details in pom.xml

2. If you want to send the common business jar package or the Maven plug-in jar package to the Maven private server, how should you configure it? In fact, it is to explain how to use the repository element and snapshotRepository element under the distributionManagement element in pom.xml?

We have already talked about how to build the host warehouse in Nexus before, and how to obtain the link of the host warehouse. The following test-devis the host warehouse of the release version component, test-snapshotbut the host warehouse of the snapshot version component, as follows:

insert image description here

Whether it is a common business jar package or a Maven plug-in jar package, the configuration in pom.xml is the same. In pom.xml, as long as versionit -SNAPSHOTends with , it is a snapshot version component, which needs to be sent to the snapshot version component host warehouse. Otherwise, it needs to be sent to the release version component host warehouse. Let's take an example directly, as follows:

<distributionManagement>
    <repository>
        <id>admin</id>
        <url>http://192.168.139.133:31743/repository/test-dev/</url>
    </repository>
    <snapshotRepository>
        <id>admin</id>
        <url>http://192.168.139.133:31743/repository/test-snapshot/</url>
    </snapshotRepository>
</distributionManagement>

In the above settings.xmlelements profile, the only elements that can be used are repositories, pluginReporitories, activeProfiles, so the configuration of submitting the jar package to the maven private server can only be written in pom.xml. The above is the configuration information of uploading the jar package in pom.xml . The configuration information for uploading the jar package is only related to the above configuration and the server element in settings.xml. After all, the Maven private server user information recorded in the server must be used.

A picture is worth a thousand words, so let’s describe it with pictures:

insert image description here
According to the real situation, let's take another picture to illustrate:
insert image description here

3. Relevant knowledge points

(1) Dependency scope

Everyone should have seen this way of writing in pom.xml:

<dependency>
	<groupId>junit</groupId>
	<artifactId>junit</artifactId>
	<version>4.10</version>
	<scope>test</scope>
</dependency>

Among them, there is a very special scope element. The value of this element will affect the scope of use of dependencies. The scope of dependencies includes compilation, testing, and running environments. The following introduces the relevant values:

  • compile: Compile dependency range, which is the default value and can be used in compilation, testing, and running environments, for example: spring-core dependency

  • test: Test dependency scope, only available in test environment, for example: JUnit dependency

  • Provided: The scope of dependencies has been provided, which can be used in both compilation and test environments, but the runtime environment is invalid, for example: servlet-api, since the jar package is already provided when running in the tomcat container, there is no need for maven to repeatedly introduce it up

  • runtime: runtime dependency range, only valid in test and runtime environments, but invalid in compilation environments, for example: JDBC driver implementation

  • system: System dependency range, which can only be used in the compilation and test environment, but is invalid at runtime. The dependencies using this range must display the relative path of the specified dependency file through the systemPath element. The basic usage is that the jar package is not in the maven warehouse. Instead, put it directly in the project, and then import the project in this way. Although there is a scope feature, since it is introduced into the project, it still wants to be used in the runtime environment, so it is necessary to package the dependency when packaging
    . Let me give you an example of an actual usage scenario. The product requires me to complete a function of splitting word documents based on section breaks, so I used it spire.doc.free-5.2.0.jarand modified the bytecode file content of the jar package. However, our company Maven The private server Nexus doesn’t know who to ask to give me permission to upload the jar package, so I put the jar package directly in the project, and then import it through the dependency of type system, and when setting the package, it needs to be packaged. This kind of dependency finally completes the use of the jar package in the project, as follows:
    insert image description here

  • import (Maven 2.9.0 and above): import the dependency range, which has nothing to do with compilation, testing, and runtime environments. This dependency range is only valid under the dependencyManagement element, and its function is to import the dependencyManagement element in the target module pom.xml And merge it into the dependencyManagement element in the pom.xml of the current module. Generally, the packaging method of the target module is pom, which is specially used for inheriting modules. In this case, the value of the type element must be pom, which is mentioned above past, for example:

    <!-- SpringBoot的依赖配置-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-dependencies</artifactId>
        <version>2.5.14</version>
        <type>pom</type>
        <scope>import</scope>
    </dependency>
    

    Summarize the relationship between dependency scope and compilation, testing, and runtime environments:

    insert image description here

(2) Transitive dependency

Assuming that module A directly depends on module B, and module B depends on module C and module D, if there is no transitive dependency, it is necessary to write not only the dependency coordinate information of module B in the pom.xml of module A, but also the module C and module D information.

Due to the existence of transitive dependencies, Maven will resolve each direct dependency (such as dependent module B), and then introduce indirect dependencies (such as module C and module D) into module A through transitive dependencies.

So transitive dependencies facilitate the operation of introducing dependencies

(3) Dependency scope and transitive dependency

If A depends on B, and B depends on C (that is, A --> B --> C), then A is the first direct dependency of B, and B is the second direct dependency of C, and C is a transitive dependency of A .

The scope of the first direct dependence and the scope of the second direct dependence determine the scope of the transitive dependence. The left side of the figure below represents the first direct dependence scope, while the top represents the second direct dependence scope, and the intermediate result represents the transitive dependence scope. as follows:

insert image description here
Combined with the above description of the scope of dependencies, the scope of transitive dependencies can determine the circumstances under which transitive dependencies can be used, that is, whether module A can use transitive dependencies C when compiling, testing, and running.

(4) Dependency mediation (that is, the same groupId and artifactId, but different version dependencies, which one will be used in the end?)

The transitive dependencies have been explained above. Because the same groupId and artifactId cannot exist in the maven project, but the dependencies of different versions, but the transitive dependencies may cause this choice dilemma. We do not know which version of the dependency plays a role effect. Assuming that there are the following two dependencies, it is necessary to judge which version of the dependency is available through the dependency adjustment principle

  • Case 1: Module A has this dependency: A->B->C->X (1.0), A->D->X (2.0)
  • Case 2: Module A has this dependency: A->B->Y (1.0), A->D->Y (2.0), assuming that A depends on B and is written in front of pom.xml

For these two situations, the first principle and the second principle of dependent regulation can be used to solve the problem respectively:

  • The first principle of dependency adjustment: the closest path is preferred. For the above case 1, that is the closest to A->DX (2.0), so the version that depends on X is 2.0
  • The second principle of dependence adjustment: the first declarant takes precedence. When the first principle cannot be used to judge, then use the second principle to judge. For the above case 2, since A depends on B and is written in front of pom.xml, the version that depends on Y is 1.0

(5) Maven properties

Simply put, it is the attribute defined at A, which can be ${属性名称}referenced in this way at B to achieve the effect that one modification takes effect everywhere. There are 6 types in total. This writing method is used in pom.xml, configuration files, and maven plug-ins. may be used.

By default, only pom.xmlthe ones in Maven属性will be parsed, and src/main/resourcesthe resource directories in will not be parsed, but maven插件the ones used in maven属性can also be parsed

  • built-in properties
    insert image description here

  • POM properties
    I am adding one based on the following types ${project.basedir}. This is also the root directory of the project and is often used in pom.xml, but I did not find the property in the super Pom basedir, but it does not affect the use
    insert image description hereinsert image description here

  • Custom properties
    We often customize pom under elements, but we can also customize pom through elements under elements in pom.xml, as follows: Of course , what is shown in the book is to customize Maven properties through elements in , as follows:propertiessettings.xmlprofileproperties
    insert image description here
    pom.xmlproperties
    insert image description here

  • Settings property
    insert image description here

  • Java system properties
    insert image description here

  • environment variable properties
    insert image description here

  • Usage expansion:
    In the same large project, there are also parent-child modules. Under normal circumstances, the groupId and version of the parent module are consistent with those of the sub-modules, and there is also a relationship between sub-modules, such as B, C, and D. It is a submodule of module A. When importing the dependencies of modules C and D in module B, you can replace the groupId and artifactId in modules C and D with POM attributes, even if you import modules in the form of parent elements in module B The groupId and artifactId of A have no effect either, I have tried it in the RuoYi project.
    insert image description here

(6) Mechanism for resolving dependencies from warehouses

insert image description here
insert image description here
insert image description here
insert image description here
insert image description here
insert image description here
insert image description here

(7) Aggregation

1) Function

Build once, work everywhere

For a large project, there must be many sub-modules in it, so one of the effects I want to achieve is that if I perform an operation such as mvn clean deploy on the aggregated project, then all sub-modules will perform the same operation to achieve full-motion the goal of

2) Implementation method

Add attributes to the aggregation module modules>module, and then write the relative position information of other modules in the attribute value. Let’s take Ruoyi as an example, as follows:

insert image description here

3) Points to note

  • The packaging method of the aggregation module must be pom, that is<packaging>pom</packaging>
  • The value of the module element is the module directory name, not the value of artifactId
  • There is no need to pay attention to the construction order, because the aggregation module will automatically calculate the construction order when it is built, and it has nothing to do with the declaration in the modules element
  • The aggregated module and the aggregated module do not have to be a parent-child relationship. If it is a horizontal relationship, it needs to be added before the value in the module element. That is to say, the value in the module ../is a relative position, as long as the aggregated module can be found through this value that's it

(8) inheritance

1) Function

One modification takes effect everywhere. Once declared in the parent module, it can be used in the submodule. If there is a change in the parent module in the future, it can be automatically changed in the submodule.

For example, if we define version in the parent module, and then the submodule inherits the version of the parent module, then only need to modify the value of version in the parent module in the future, and the value of version in all submodules will naturally change. This is just another change, such as dependencies, plug-ins, builds, common project component download warehouses, and plug-in component download warehouses can all be inherited

2) Implementation method

In general, we declare gav, dependencyManagement, dependencies, build, repositories, pluginRepositories in the parent module pom.xml, then they can be used in submodules

For gavthe coordinates, the submodule can inherit the parent module gv, and then only artifactIdneed to write one. The example is as follows:

insert image description here

For dependencyManagementdependency management, the dependency management defined in the parent module will not be inherited by default in the submodule, but it can be inherited by only writing ga in the dependencies element, because the version has been specified by the parent module , of course, you can also override the version given in the parent module by specifying the version, examples are as follows:

insert image description here

For dependencies dependencies, submodules will completely inherit the dependencies of the parent module, but this kind of writing is relatively rare. Generally, submodules are selected on demand through dependency management. Of course, submodules can also be included in the dependencies themselves. Write gav coordinates to override parent module dependencies

For build, repositories, pluginRepositories, submodules will completely inherit the parent module, and can also override the configuration information given by the parent module by rewriting

3) Points to note

  • The packaging method of the parent module must be pom, that is<packaging>pom</packaging>
  • The parent-child module does not have to be a parent-child directory relationship. If it is a horizontal relationship, it needs to be added to the parent element of the child module, relativePath元素and then specify the relative position of the parent module in it ../父模块目录名称/pom.xml. That is to say, if the parent-child module is not a parent-child directory, then It is necessary parent>relativePathto specify the relative position of the parent module in the element of the submodule. For relativePath元素Ruoyi, the default value is ../pom.xml, since Ruoyi’s submodule and parent module are parent-subdirectory relationships, the default relativePath元素value can be used directly, and we will make it explicit Declare it for everyone to see the specific usage:
    insert image description here

(9) The relationship between aggregation and inheritance

In most cases, the aggregation module and the parent module are the same module, and 子模块 / 被聚合模块the relationship between the module and the parent-child module is like this in Ruoyi, as follows:

insert image description here

Example parent module:

<?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">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.ruoyi</groupId>
    <artifactId>ruoyi</artifactId>
    <version>4.7.5</version>

    <name>ruoyi</name>
    <url>http://www.ruoyi.vip</url>
    <description>若依管理系统</description>
    
    <properties>
        <!-- 依赖version -->
        <ruoyi.version>4.7.5</ruoyi.version>
        <!-- 编码方式 -->
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <!-- jdk版本 -->
        <java.version>1.8</java.version>
        <maven-jar-plugin.version>3.1.1</maven-jar-plugin.version>
        <shiro.version>1.9.1</shiro.version>
        <thymeleaf.extras.shiro.version>2.1.0</thymeleaf.extras.shiro.version>
        <druid.version>1.2.11</druid.version>
        <bitwalker.version>1.21</bitwalker.version>
        <kaptcha.version>2.3.2</kaptcha.version>
        <swagger.version>3.0.0</swagger.version>
        <mybatis-spring-boot.version>2.2.2</mybatis-spring-boot.version>
        <pagehelper.boot.version>1.4.3</pagehelper.boot.version>
        <fastjson.version>1.2.83</fastjson.version>
        <oshi.version>6.2.2</oshi.version>
        <commons.io.version>2.11.0</commons.io.version>
        <commons.fileupload.version>1.4</commons.fileupload.version>
        <poi.version>4.1.2</poi.version>
        <velocity.version>2.3</velocity.version>
    </properties>

    <!-- 依赖声明 -->
    <dependencyManagement>
        <dependencies>

            <!-- SpringBoot的依赖配置-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>2.5.14</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            ……

        </dependencies>
    </dependencyManagement>

    <modules>
        <module>ruoyi-admin</module>
        <module>ruoyi-framework</module>
        <module>ruoyi-system</module>
        <module>ruoyi-quartz</module>
        <module>ruoyi-generator</module>
        <module>ruoyi-common</module>
    </modules>
    <packaging>pom</packaging>


    <dependencies>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.1</version>
                <configuration>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                    <encoding>${project.build.sourceEncoding}</encoding>
                </configuration>
            </plugin>
        </plugins>
    </build>

    <repositories>
        <repository>
            <id>public</id>
            <name>aliyun nexus</name>
            <url>https://maven.aliyun.com/repository/public</url>
            <releases>
                <enabled>true</enabled>
            </releases>
        </repository>
    </repositories>

    <pluginRepositories>
        <pluginRepository>
            <id>public</id>
            <name>aliyun nexus</name>
            <url>https://maven.aliyun.com/repository/public</url>
            <releases>
                <enabled>true</enabled>
            </releases>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </pluginRepository>
    </pluginRepositories>

</project>

Examples of submodules:

<?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>ruoyi</artifactId>
        <groupId>com.ruoyi</groupId>
        <version>4.7.5</version>
        <!-- ../pom.xml是默认值,特意写出来让大家看下配置方法 -->
        <relativePath>../pom.xml</relativePath>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <packaging>jar</packaging>
    <artifactId>ruoyi-admin</artifactId>

    <description>
        web服务入口
    </description>

    <dependencies>

        <!-- SpringBoot集成thymeleaf模板 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>

        ……

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>2.1.1.RELEASE</version>
                <configuration>
                    <fork>true</fork> <!-- 如果没有该配置,devtools不会生效 -->
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>3.0.0</version>
                <configuration>
                    <failOnMissingWebXml>false</failOnMissingWebXml>
                    <warName>${project.artifactId}</warName>
                </configuration>
            </plugin>
            <!-- YUI Compressor (CSS/JS压缩)
            <plugin>
                <groupId>net.alchim31.maven</groupId>
                <artifactId>yuicompressor-maven-plugin</artifactId>
                <version>1.5.1</version>
                <executions>
                    <execution>
                        <phase>prepare-package</phase>
                        <goals>
                            <goal>compress</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <encoding>UTF-8</encoding>
                    <jswarn>false</jswarn>
                    <nosuffix>true</nosuffix>
                    <linebreakpos>50000</linebreakpos>
                    <sourceDirectory>src/main/resources/static</sourceDirectory>
                    <force>true</force>
                    <includes>
                        <include>**/*.js</include>
                        <include>**/*.css</include>
                    </includes>
                    <excludes>
                        <exclude>**/*.min.js</exclude>
                        <exclude>**/*.min.css</exclude>
                        <exclude>**/fileinput.js</exclude>
                        <exclude>**/bootstrap-table/**</exclude>
                    </excludes>
                </configuration>
            </plugin> -->
        </plugins>
        <finalName>${project.artifactId}</finalName>
    </build>

</project>

(10) Life cycle and plug-ins

List of commonly used plugins:

insert image description here
insert image description here

1) What is the life cycle

Maven contains three sets of completely independent life cycles, namely clean, default, and site. The function of the clean life cycle is to clean up the project, while the function of the default life cycle is to build the project, and the purpose of the site life cycle is to build the project site. Use the site lifecycle sparingly. will be explained in detail below

2) What are the life cycle stages

Take the Ruoyi project as an example. When we open the Ruoyi project through IDEA, then click the Maven button on the right, and then find any module to open, everyone will see Lifecycle. The red box in the figure below is our most commonly used one. Life cycle phases, including: clean, compile, test, package, install, deploy...

insert image description here

3) What is a plugin

A plugin is a collection of plugin targets

4) What is the plugin goal

According to programming, if the life cycle phase is an interface, then the plug-in target is the implementation class, and the plug-in contains one or more plug-in targets

5) Relationship between life cycle, life cycle phase, plug-in, and plug-in target

A lifecycle corresponds to one or more lifecycle phases, and a lifecycle phase corresponds to a plugin goal, and a plugin corresponds to one or more plugin goals

6) Detailed explanation of the life cycle

  • Three sets of life cycles: Maven contains three completely independent life cycles, namely clean, default, and site. The function of the clean life cycle is to clean up the project, while the function of the default life cycle is to build the project, and the purpose of the site life cycle is Build a project site, rarely use the site life cycle
  • Life cycle phase: Although the three sets of life cycles are independent of each other, for each set of life cycle, calling the later life cycle phase will definitely trigger the previous life cycle phase, so we only need to specify when mvn clean packagepackaging It’s ok, although the clean life cycle includes not only the clean phase, but of course the default life cycle also includes many phases, but according to the principle that triggering the later life cycle phase will trigger the previous life cycle phase, so the command we package is very concise . Of course, since each set of life cycles is independent of each other, we need to execute the clean phase first, and then execute the package phase. The stages in each life cycle are given below
    • clean life cycle
      insert image description here

    • default life cycle
      insert image description here
      insert image description here

    • site life cycle
      insert image description here

7) Detailed explanation of plugins and plugin goals

  • Plug-in function: a plug-in can do many things, that is to say, it contains multiple plug-in targets

  • Function of the plug-in target: a plug-in corresponds to a plug-in target, each plug-in target is a function, and each plug-in target will perform the things described in the above life cycle stages, as follows:
    insert image description here

  • Binding of life cycle phases and plug-in goals: The Maven life cycle and plug-ins are bound to each other to complete the actual construction tasks. For example, the task of project compilation corresponds to the compile phase of the default life cycle, and is then implemented by the compile goal of the maven-compiler-plugin plugin. After the two are bound, the relevant tasks can be completed
    insert image description here

  • Built-in bindings for lifecycle and plugin goals:

    • The binding relationship between the clean life cycle phase and the plug-in target
      insert image description here

    • The binding relationship between the default life cycle phase and the plug-in target
      insert image description here

    • The binding relationship between the site life cycle phase and the plug-in target
      insert image description here

  • Customizing the binding relationship between the life cycle and the plug-in target:
    the following is the process of customizing the binding relationship. Due to the existence of this binding method, multiple plug-in targets can be bound to the same stage. The sequence of these plug-in declarations determines the The execution order of the targets.
    insert image description here
    insert image description here

  • Command-line plug-in configuration:
    The following approach is often seen in Dockerfile, by setting the parameters of the plug-in target to skip the test.

insert image description here

8) Parsing process of plug-in groupId and artifactId in pom.xml

We can see that sometimes pluginit is not necessary to write groupIdthe sum artifactId, which depends on the parsing mechanism of the groupIdsum artifactId.

groupId: If we omit it groupId, Maven will think that the plug-in is the official plug-in of Maven, so groupIdit will be considered to be org.apache.maven.plugins. Of course, there are many official plug-ins of Maven. For example:
insert image description here

version: If we omit it version, this needs to be discussed on a case-by-case basis. For some cases where the plug-in version has been defined in the super Pom, the default version will be used. For maven3.5.4 version, the version has already been set The plug-in information is as follows:

insert image description here

If the version of the plug-in is not defined in the super pom, for Maven3, the latest release version in all warehouses is used by default at present, and all warehouses include: local plug-in warehouse and remote plug-in warehouse, but this approach is not recommended, after all Each version of the plug-in is different, so it is recommended to fix the plug-in version. The following is a detailed explanation:

insert image description here
insert image description here

9) The plug-in prefix parsing process in the mvn command line

We often use mvn clean packagethis method to mavenperform related operations. This method is the life cycle phase of the operation, and the plug-in target is operated through the life cycle phase.

mvnThen if I want to directly operate the plug-in target, this leads to the specific method used in the command line , as follows:

mvn [options] [<goal(s)>][<phase>(s)]

Our above life cycle specifies phasethe usage in the above command. Now let’s talk about goalthe usage in the above command. This is the method of calling the plug-in target directly through the command line

Let's talk about goalthe usage of the above command. When we execute it in the console mvn dependency:tree, we must specify the gav coordinates and target of the plug-in when we call mvn dependency:treethe dependencyplug- treein target. How to dependencyfind complete plugin coordinates by artifactId prefix gav. By default, groupIdthe default value is assigned to org.apache.maven.pluginsor org.codehaus.mojo, as org.apache.maven.pluginsan example, maven will search in the local warehouse org/apache/maven/plugins/maven-metadata.xml. Currently, the file name in my file is maven-metadata-central.xml. I feel that this name should be related to the value of the plug-in warehouse configured in pom.xmlor . Open this The file can see the following content:settings.xmlid

insert image description here
dependencyYou can find the real value of artifactId by searching the prefix maven-dependency-plugin, groupIdand now artifactIdyou have both. At this time, you can get the value according to the parsing method mentioned in the parsing process of the plug-in groupId and artifactId in pom.xml above . Now the plug-in is complete, and then combined with the target You can complete the call of the plug-in targetversionversiongavtree

mvn artifactId前缀:目标It is also mentioned in the book that if we write a plug-in ourselves, we can also call and execute it through the command line. First, we need to put a released version of the plug-in 本地仓库/远程仓库, and then configure the location information 在settings.xmlof the parsing rule file prefixed with the artifactId of our plug-in . maven-metadata-仓库id.xmlThis is our own groupIdvalue, the specific configuration method is:

insert image description here
So we also imitate the configuration method in the local warehouse org/apache/maven/plugins/maven-metadata-central.xmlto configure our own . When using this maven-metadata-仓库id.xmlon the command line, we can find ours according to the configuration information in (Note: the warehouse id value configured in pom.xml or settings.xml may be It needs to be configured at the back of the xml file to take effect), and then find the real value of artifactId. Now that both groupId and artifactId are available, you need to find the version according to the automatic version search rule. When the gav coordinates are complete, you can call the plug-in target Now, we have finally completed calling the goals in our own Maven plug-in through the command linemvn artifactId缩写:目标settings.xmlmaven-metadata-仓库id.xml

4. Explanation of the role of elements

pom.xml element reference:
insert image description here
insert image description here

(1)modelVersion

  • Meaning: The version of the Pom model
  • Explanation: According to the explanation in the book, we can know that for Maven 2 and Maven 3, it can only be 4.0.0, which comes from P28 of "Maven Combat"

(2)groupId、artifactId、version

  • groupId: Organization id, generally the reverse order of the company domain name + project name, or directly the reverse order of the company domain name, such as: com.atguigu.netiler, com.ruoyi
  • artifactId: component id, generally the module (subproject) name, for example: kms-wiki
  • version: component version, generally divided into snapshot version and release version

(3)parent

  • Meaning: Declare the inherited parent component information, which is convenient for the unified control of the dependency version of the child component through the pom. element, pluginRepositories element); the usage of the parent element is introduced in detail in the "Aggregation and Inheritance" chapter
  • How to use: Let’s use the Ruoyi project as an example:
<parent>
    <artifactId>ruoyi</artifactId>
    <groupId>com.ruoyi</groupId>
    <version>4.7.5</version>
</parent>

<artifactId>ruoyi-system</artifactId>

The relationship diagram is as follows:

insert image description here

  • important point:
    • In the parent element, you need to write the gav coordinate value of the parent component. The parent component does not necessarily have to have a two-level directory relationship with the child component. In the parent element, you can use the relativePath element to specify the relative path of the parent component pom.xml, where The default value of the relativePath element is ../pom.xml, the default value represents that the parent component and the child component belong to the parent-child directory, so in general, we do not configure the value of the relativePath element if we write the parent component and the child component as a parent-child directory
    • The child component can inherit the groupId and version of the parent component, but the artifactId element must be rewritten, of course, the groupId and version of the parent component can also be written

(4)modules

  • Meaning: Declare other modules in the aggregation module to build other modules in a unified way, such as executing mvn clean deploycommands to perform unified publishing operations on all other modules
  • How to use: Let’s use the Ruoyi project as an example:
<modules>
    <module>ruoyi-admin</module>
    <module>ruoyi-framework</module>
    <module>ruoyi-system</module>
    <module>ruoyi-quartz</module>
    <module>ruoyi-generator</module>
    <module>ruoyi-common</module>
</modules>

The relationship diagram is as follows:

insert image description here

  • important point:
    • The value of the module element is the module directory name, not the value of artifactId

(5)packaging

  • Meaning: packing method
  • Default value: jar, that is, if this value is not set, it will be a jar package
  • Optional values:
    • jar: jar package, the default value
    • war: make war package
    • pom: aggregate project, inherit parent project
    • maven-plugin: Play the maven plugin, but the result is also a jar package
  • Example:<packaging>maven-plugin</packaging>

(6)name

  • Meaning: The name of the module, just for display, for example:<name>ruoyi</name>

(7)description

  • Meaning: module description, just for display, for example:<description>若依管理系统</description>

(8) Several less commonly used project information elements

  • organization: the organization to which it belongs
  • licenses (collection) "license: license
  • mailingLists (collection) "mailingList: mailing list
  • developers (collection) "developer: developer
  • Contributors (collection) "contributor: Contributor
  • issueManagement: issue tracking system
  • ciManagement: continuous tracking system
  • scm: version control system

(9)properties

  • Meaning: Maven attribute, the information configured here is provided for other locations, such as: dependencies, dependencyManagement, build. The reason for putting it here is to facilitate unified modification. For example, setting it in the parent module can uniformly control the dependent version version of the sub-module. One modification will take effect everywhere. You can place the dependent version, encoding method, jdk version, etc. Our company's
    architects A lot of properties are written in the parent module, combined with dependencyManagement to control the dependency version, so they directly handle the situation of dependency conflicts and version conflicts. For us users, we don't have to worry about dependency conflicts between dependencies. , for their contributions to advancing the work
  • Example:
<properties>
    <!-- 依赖version -->
    <ruoyi.version>4.7.5</ruoyi.version>
    <!-- 编码方式 -->
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <!-- jdk版本 -->
    <java.version>1.8</java.version>
    <maven-jar-plugin.version>3.1.1</maven-jar-plugin.version>
    <shiro.version>1.9.1</shiro.version>
    <thymeleaf.extras.shiro.version>2.1.0</thymeleaf.extras.shiro.version>
    <druid.version>1.2.11</druid.version>
    <bitwalker.version>1.21</bitwalker.version>
    <kaptcha.version>2.3.2</kaptcha.version>
    <swagger.version>3.0.0</swagger.version>
    <mybatis-spring-boot.version>2.2.2</mybatis-spring-boot.version>
    <pagehelper.boot.version>1.4.3</pagehelper.boot.version>
    <fastjson.version>1.2.83</fastjson.version>
    <oshi.version>6.2.2</oshi.version>
    <commons.io.version>2.11.0</commons.io.version>
    <commons.fileupload.version>1.4</commons.fileupload.version>
    <poi.version>4.1.2</poi.version>
    <velocity.version>2.3</velocity.version>
</properties>

(10)dependencyManagement

  • Meaning: Dependency management, generally written in the parent module, and then provide dependency management for the submodule, then when the submodule is in use, only need to write groupId and artifactId, and the version can be controlled by the parent module, of course, if the submodule writes version, it will overwrite the version in the parent module
  • Example:
<!-- 依赖声明 -->
<dependencyManagement>
    <dependencies>
    
        <!-- SpringBoot的依赖配置-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>2.5.14</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
        
        <!-- 阿里数据库连接池 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>${
    
    druid.version}</version>
        </dependency>
        
        <!-- 阿里JSON解析器 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>${
    
    fastjson.version}</version>
        </dependency>

        <!-- 定时任务-->
        <dependency>
            <groupId>com.ruoyi</groupId>
            <artifactId>ruoyi-quartz</artifactId>
            <version>${
    
    ruoyi.version}</version>
        </dependency>

        <!-- 代码生成-->
        <dependency>
            <groupId>com.ruoyi</groupId>
            <artifactId>ruoyi-generator</artifactId>
            <version>${
    
    ruoyi.version}</version>
        </dependency>

        <!-- 核心模块-->
        <dependency>
            <groupId>com.ruoyi</groupId>
            <artifactId>ruoyi-framework</artifactId>
            <version>${
    
    ruoyi.version}</version>
        </dependency>

        <!-- 系统模块-->
        <dependency>
            <groupId>com.ruoyi</groupId>
            <artifactId>ruoyi-system</artifactId>
            <version>${
    
    ruoyi.version}</version>
        </dependency>

        <!-- 通用工具-->
        <dependency>
            <groupId>com.ruoyi</groupId>
            <artifactId>ruoyi-common</artifactId>
            <version>${
    
    ruoyi.version}</version>
        </dependency>

    </dependencies>
</dependencyManagement>

(11)dependencies

  • Meaning: Dependency, the most basic of which should also be written gav, of course you can see that some of the following dependencies do not have a version, that is because they will inherit the version from the dependencyManagement element of the parent module; of course, in addition to the gav coordinates, there are other Elements can be written in the dependency dependency, these elements also have type, scope, optional, exclusions
  • Example:
<dependencies>

    <!-- SpringBoot集成thymeleaf模板 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>

    <!-- spring-boot-devtools -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <optional>true</optional> <!-- 表示依赖不会传递 -->
    </dependency>

    <!-- swagger3-->
    <dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-boot-starter</artifactId>
    </dependency>

    <!-- 防止进入swagger页面报类型转换错误,排除3.0.0中的引用,手动增加1.6.2版本 -->
    <dependency>
        <groupId>io.swagger</groupId>
        <artifactId>swagger-models</artifactId>
        <version>1.6.2</version>
    </dependency>

    <!-- Mysql驱动包 -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
    </dependency>

    <!-- 核心模块-->
    <dependency>
        <groupId>com.ruoyi</groupId>
        <artifactId>ruoyi-framework</artifactId>
    </dependency>

    <!-- 定时任务-->
    <dependency>
        <groupId>com.ruoyi</groupId>
        <artifactId>ruoyi-quartz</artifactId>
    </dependency>

    <!-- 代码生成-->
    <dependency>
        <groupId>com.ruoyi</groupId>
        <artifactId>ruoyi-generator</artifactId>
    </dependency>

</dependencies>
  • Why version can be omitted: that is because this is a submodule, and the gav coordinates have been defined in the dependencyManagement element of the parent module, so after the submodule inherits the module, it only needs to write ga, and the version is directly from the parent module that got
  • Usage of other elements:
    • type: dependency type, which is the packaging type of the corresponding dependency. The default is jar, but it needs to be specified in some cases. Examples are as follows:

      <!-- SpringBoot的依赖配置-->
      <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-dependencies</artifactId>
          <version>2.5.14</version>
          <type>pom</type>
          <scope>import</scope>
      </dependency>
      
    • scope: Dependency scope, used to control the relationship that depends on compilation, testing, and runtime environment. For details, please refer to the section on Dependency Scope above

    • optional: Mark dependency is optional, for example, module A depends on module B, and module B depends on modules X and Y, but modules X and Y cannot coexist, for example, module B is a persistence layer framework, and module X and module Y are respectively It is a dependency package of mysql and Oracle. At this time, it is necessary to use optional dependencies on dependency X and dependency Y in module B. This dependency method will not affect the use of module B on module X and module Y, nor will it affect the module A dependency conflict occurs when A depends on module B, and it can provide module A with a reference to the implementation of the specific persistence layer. Since optional dependencies cannot be passed, it is necessary to display the life module X and module Y in module A

    • Exclusions: Exclude related dependencies. As we all know, in the dependencies after Maven parses, there will not be two dependencies with the same groupId and artifactId but different versions. If we want Maven to generate dependent jar packages according to our requirements, at this time We need to tell Maven which one we want to depend on. To achieve this goal, we must know the principle of dependency adjustment. For details, please refer to the section on dependency adjustment above.

(12)build

1) finalName

  • Meaning: the package name of the jar package or war package, the default value is artifactId-version.打包方式, now it becomesfinalName.打包方式
  • Usage: For a maven project, the startup command in the Dockerfile is generally written java -jar XXX.jar. If the default packaging method is used, then when we change the project version, we also need to change the jar package name in the Dockerfile. This is very troublesome. If we customize the finalName Value, then when we modify the version, we don’t need to modify the jar package name in the Dockerfile
  • Example:
<build>
    <finalName>${
    
    project.artifactId}</finalName>
</build>

The relationship diagram is as follows:

insert image description here

2)sourceDirectory

  • Meaning: custom source code directory

  • Function: The source code of some old projects in the company was written under the source directory instead, but it is src/main/javanot likely to be changed, so as not to make mistakes, so this parameter needs to be set

  • Note: According to the principle that the Maven convention is superior to configuration, by default maven has defined the source code directory (src/main/java), compilation output directory (target/classes), packaging method (jar), and package output in the super pom directory (target). If it's just because of preference, then don't play with personality. Personality often means sacrificing versatility and adding unnecessary complexity.

  • Example:

    <build>
        <sourceDirectory>source</sourceDirectory>
    </build>
    

3)resources

  • Meaning: Customize the main resource file directory

  • Function: The configuration files in some projects of the company are not written src/main/resourcesunder the directory, but placed configbelow, so it is necessary to customize the main resource file directory

  • Example:

    <build>
    	<resources>
    		<resource>
    			<directory>config</directory>
    			<excludes>
    				<exclude>**/*.java</exclude>
    			</excludes>
    		</resource>
    	</resources>
    </build>
    
  • The relationship diagram is as follows:
    insert image description here

  • Resources resource directory filtering
    has already described the role of Maven attributes above, and also know that only the Maven attributes in pom.xml can also be automatically parsed, but the Maven attributes of files in src/main/resources cannot be automatically parsed, so we You need to specify the files in the resource directory that need to be parsed.
    As long as we specify the location of the resource resource directory, it will overwrite the location of the resource resource directory in the super Pom. Since we want to specify the files in the filtered resource directory, we need to add the filtering attribute and set it to true, and the default is false.
    Below we introduce an example of enabling filtering for the main resource directory and the test resource directory:
    insert image description here
    insert image description here
    Of course, you can also configure multiple resource directories and enable/disable filtering for them, as follows:
    insert image description here
    insert image description here

  • Web resource directory filtering
    For webprojects, there are not only src/main/resourcesresource directories, but also another type of webresource files src/main/webapp. In some cases, we also need to web资源文件enable filtering.
    It is mentioned in the book that "readers need to distinguish between general resource files and web resource files in web projects. The former is processed by maven-resource-plugin, while the latter is processed by maven-war-plugin.", written as follows:
    insert image description here

4)plugin

I don’t understand plug-ins either, so I’ll list the frequently-used plug-ins.
insert image description here
insert image description here
Above we also described the relationship between the life cycle and plug-ins, as well as the detailed information of the plug-ins.

(13)profiles

For detailed usage, refer to the usage of the profiles element in settings.xml described above. The usage is the same, but this element is rarely used in pom.xml

(14)distributionManagement》repository

  • Meaning: Define the release version deployment warehouse, that is, send the official version jar package to the maven private server, regardless of whether the jar package is a normal project or a maven plug-in. You can refer to this section
    in pom.xml想把普通业务jar包或者Maven插件jar包发送到Maven私服中,应该怎么配置

  • Example:
    The ip inside is the nexus-Maven private server built by myself, and the account information referred to in the id is also written in the settings.xml

    <distributionManagement>
        <repository>
            <id>admin</id>
            <url>http://192.168.139.133:31743/repository/test-dev/</url>
        </repository>
        <snapshotRepository>
            <id>admin</id>
            <url>http://192.168.139.133:31743/repository/test-snapshot/</url>
        </snapshotRepository>
    </distributionManagement>
    

(15)distributionManagement》snapshotRepository

  • Meaning: Define the snapshot version deployment warehouse, that is, send the snapshot version jar package to the maven private server, regardless of whether the jar package is a normal project or a maven plug-in. You can refer to this section
    in pom.xml想把普通业务jar包或者Maven插件jar包发送到Maven私服中,应该怎么配置
  • The ip in the example
    is the nexus-Maven private server built by myself, and the account information referred to in the id is also written in the settings.xml
    <distributionManagement>
        <repository>
            <id>admin</id>
            <url>http://192.168.139.133:31743/repository/test-dev/</url>
        </repository>
        <snapshotRepository>
            <id>admin</id>
            <url>http://192.168.139.133:31743/repository/test-snapshot/</url>
        </snapshotRepository>
    </distributionManagement>
    

(16)repositories》repository

  • Meaning: Download the repositories that ordinary projects (non-Maven plugins) depend on, without distinguishing between release version dependencies and snapshot version dependencies
  • Example:
    Let's use Ruoyi's parent pom.xml as an example, as follows:
    insert image description here

(17)pluginRepositories》pulginRepository

  • Meaning: Download the warehouse that the Maven plug-in (non-ordinary project) depends on, without distinguishing between release version dependencies and snapshot version dependencies
  • Example:
    Let's use Ruoyi's parent pom.xml as an example, as follows:
    insert image description here

6. Maven plugin

1. Function

Write once, use by multiple people, reduce repetitive coding process

for example:

  • Write a plug-in that counts the number of lines of code
  • Generate Dockerfile, Jenkinsfile, YamlStatefulSet.yaml in the project, and add plugins for related tasks in Jenkins

2. Precautions

  • Packaging method: The packaging method needs to be maven-plugin, that is, to be configured in pom.xml<packaging>maven-plugin</packaging>

  • Common dependencies:

    <dependency>
        <groupId>org.apache.maven</groupId>
        <artifactId>maven-plugin-api</artifactId>
        <version>3.6.0</version>
    </dependency>
    <dependency>
        <groupId>org.apache.maven.plugin-tools</groupId>
        <artifactId>maven-plugin-annotations</artifactId>
        <version>3.6.0</version>
        <scope>provided</scope>
    </dependency>
    
  • Plug-in prefix setting:
    The value of the generate element below is the plug-in prefix, and the default plug-in prefix is artifactId​​the value

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-plugin-plugin</artifactId>
                <version>3.6.4</version>
                <configuration>
                    <goalPrefix>generate</goalPrefix>
                </configuration>
            </plugin>
        </plugins>
    </build>
    

    Let’s look at the case where the default plugin prefix is ​​artifactId, as follows:
    insert image description here
    Let’s look at the situation where the plugin prefix is ​​specified by us, as follows:
    insert image description here

  • Plugin target class, plugin target name, lifecycle phase settings for default bindings:
    insert image description here

  • How to use @Parameter annotation

    • defaultValue: default value, can be used Maven属性, this term can be searched globally, explained in detail in pom.xml
    • readonly: read-only, that is, users cannot configure values ​​through the configuration element
    • required: Required, that is, this attribute must have a value, whether it is filled in by the user or the default value
    • name: name, if not set, the attribute name can be used in the configuration element by default, and the name value can also be used if set
    • alias: alias, if 参数名称/name值it is too long, you can use the alias in the configuration element after defining the alias. Among them, the three setting methods of attribute name, name and alias can coexist, and can be used in the configuration element
  • How the properties defined in the plugin target class are defined in the project pom.xml created using:

    insert image description here

  • Plugin target class attribute types:
    insert image description here
    insert image description here
    insert image description here
    insert image description here

insert image description here

insert image description here
insert image description here

insert image description here

3. Differences from ordinary Maven projects

In terms of code writing, there is not much difference, just write as you want, and then there is no difference when publishing to Maven private server, but there is a difference when downloading, which needs special configuration in settings.xml , you can see the second explanation in setting.xml

4. Examples

7. Example

1. Use repositories and pluginRepositories in aggregation, inheritance, and pom.xml to download components

Take Ruoyi project as an example to illustrate the usage of aggregation and inheritance

(1) ruoyi module pom.xml (aggregate module, parent module, use repositories and pluginRepositories to download components)

<?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">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.ruoyi</groupId>
    <artifactId>ruoyi</artifactId>
    <version>4.7.5</version>

    <name>ruoyi</name>
    <url>http://www.ruoyi.vip</url>
    <description>若依管理系统</description>
    
    <properties>
        <!-- 依赖version -->
        <ruoyi.version>4.7.5</ruoyi.version>
        <!-- 编码方式 -->
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <!-- jdk版本 -->
        <java.version>1.8</java.version>
        <maven-jar-plugin.version>3.1.1</maven-jar-plugin.version>
        <shiro.version>1.9.1</shiro.version>
        <thymeleaf.extras.shiro.version>2.1.0</thymeleaf.extras.shiro.version>
        <druid.version>1.2.11</druid.version>
        <bitwalker.version>1.21</bitwalker.version>
        <kaptcha.version>2.3.2</kaptcha.version>
        <swagger.version>3.0.0</swagger.version>
        <mybatis-spring-boot.version>2.2.2</mybatis-spring-boot.version>
        <pagehelper.boot.version>1.4.3</pagehelper.boot.version>
        <fastjson.version>1.2.83</fastjson.version>
        <oshi.version>6.2.2</oshi.version>
        <commons.io.version>2.11.0</commons.io.version>
        <commons.fileupload.version>1.4</commons.fileupload.version>
        <poi.version>4.1.2</poi.version>
        <velocity.version>2.3</velocity.version>
    </properties>

    <!-- 依赖声明 -->
    <dependencyManagement>
        <dependencies>

            <!-- SpringBoot的依赖配置-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>2.5.14</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <!-- 阿里数据库连接池 -->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid-spring-boot-starter</artifactId>
                <version>${druid.version}</version>
            </dependency>

            <!-- 验证码 -->
            <dependency>
                <groupId>com.github.penggle</groupId>
                <artifactId>kaptcha</artifactId>
                <version>${kaptcha.version}</version>
            </dependency>

            <!-- Shiro核心框架 -->
            <dependency>
                <groupId>org.apache.shiro</groupId>
                <artifactId>shiro-core</artifactId>
                <version>${shiro.version}</version>
            </dependency>

            <!-- Shiro使用Spring框架 -->
            <dependency>
                <groupId>org.apache.shiro</groupId>
                <artifactId>shiro-spring</artifactId>
                <version>${shiro.version}</version>
            </dependency>

            <!-- Shiro使用EhCache缓存框架 -->
            <dependency>
                <groupId>org.apache.shiro</groupId>
                <artifactId>shiro-ehcache</artifactId>
                <version>${shiro.version}</version>
            </dependency>

            <!-- thymeleaf模板引擎和shiro框架的整合 -->
            <dependency>
                <groupId>com.github.theborakompanioni</groupId>
                <artifactId>thymeleaf-extras-shiro</artifactId>
                <version>${thymeleaf.extras.shiro.version}</version>
            </dependency>

            <!-- 解析客户端操作系统、浏览器等 -->
            <dependency>
                <groupId>eu.bitwalker</groupId>
                <artifactId>UserAgentUtils</artifactId>
                <version>${bitwalker.version}</version>
            </dependency>

            <!-- SpringBoot集成mybatis框架 -->
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>${mybatis-spring-boot.version}</version>
            </dependency>

            <!-- pagehelper 分页插件 -->
            <dependency>
                <groupId>com.github.pagehelper</groupId>
                <artifactId>pagehelper-spring-boot-starter</artifactId>
                <version>${pagehelper.boot.version}</version>
            </dependency>

            <!-- 获取系统信息 -->
            <dependency>
                <groupId>com.github.oshi</groupId>
                <artifactId>oshi-core</artifactId>
                <version>${oshi.version}</version>
            </dependency>

            <!-- Swagger3依赖 -->
            <dependency>
                <groupId>io.springfox</groupId>
                <artifactId>springfox-boot-starter</artifactId>
                <version>${swagger.version}</version>
                <exclusions>
                    <exclusion>
                        <groupId>io.swagger</groupId>
                        <artifactId>swagger-models</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>

            <!-- io常用工具类 -->
            <dependency>
                <groupId>commons-io</groupId>
                <artifactId>commons-io</artifactId>
                <version>${commons.io.version}</version>
            </dependency>

            <!-- 文件上传工具类 -->
            <dependency>
                <groupId>commons-fileupload</groupId>
                <artifactId>commons-fileupload</artifactId>
                <version>${commons.fileupload.version}</version>
            </dependency>

            <!-- excel工具 -->
            <dependency>
                <groupId>org.apache.poi</groupId>
                <artifactId>poi-ooxml</artifactId>
                <version>${poi.version}</version>
            </dependency>

            <!-- velocity代码生成使用模板 -->
            <dependency>
                <groupId>org.apache.velocity</groupId>
                <artifactId>velocity-engine-core</artifactId>
                <version>${velocity.version}</version>
            </dependency>

            <!-- 阿里JSON解析器 -->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>fastjson</artifactId>
                <version>${fastjson.version}</version>
            </dependency>

            <!-- 定时任务-->
            <dependency>
                <groupId>com.ruoyi</groupId>
                <artifactId>ruoyi-quartz</artifactId>
                <version>${ruoyi.version}</version>
            </dependency>

            <!-- 代码生成-->
            <dependency>
                <groupId>com.ruoyi</groupId>
                <artifactId>ruoyi-generator</artifactId>
                <version>${ruoyi.version}</version>
            </dependency>

            <!-- 核心模块-->
            <dependency>
                <groupId>com.ruoyi</groupId>
                <artifactId>ruoyi-framework</artifactId>
                <version>${ruoyi.version}</version>
            </dependency>

            <!-- 系统模块-->
            <dependency>
                <groupId>com.ruoyi</groupId>
                <artifactId>ruoyi-system</artifactId>
                <version>${ruoyi.version}</version>
            </dependency>

            <!-- 通用工具-->
            <dependency>
                <groupId>com.ruoyi</groupId>
                <artifactId>ruoyi-common</artifactId>
                <version>${ruoyi.version}</version>
            </dependency>

        </dependencies>
    </dependencyManagement>

    <modules>
        <module>ruoyi-admin</module>
        <module>ruoyi-framework</module>
        <module>ruoyi-system</module>
        <module>ruoyi-quartz</module>
        <module>ruoyi-generator</module>
        <module>ruoyi-common</module>
    </modules>
    <packaging>pom</packaging>


    <dependencies>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.1</version>
                <configuration>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                    <encoding>${project.build.sourceEncoding}</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>com.atguigu</groupId>
                <artifactId>count-file-lines</artifactId>
                <version>1.4-SNAPSHOT</version>
                <configuration>
                </configuration>
            </plugin>
            <plugin>
                <groupId>com.hczy.maven.plugin</groupId>
                <artifactId>link-generate-plugin</artifactId>
                <version>1.0-SNAPSHOT</version>
                <configuration>
                    <tomcatUrl>C:\test</tomcatUrl>
                </configuration>
            </plugin>
        </plugins>
    </build>

	<!-- 普通maven项目构件下载仓库 -->
    <repositories>
        <repository>
            <id>public</id>
            <name>aliyun nexus</name>
            <url>https://maven.aliyun.com/repository/public</url>
            <releases>
                <enabled>true</enabled>
            </releases>
        </repository>
    </repositories>

	<!-- maven插件下载仓库 -->
    <pluginRepositories>
        <pluginRepository>
            <id>public</id>
            <name>aliyun nexus</name>
            <url>https://maven.aliyun.com/repository/public</url>
            <releases>
                <enabled>true</enabled>
            </releases>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </pluginRepository>
    </pluginRepositories>

</project>

(2) ruoyi-admin module pom.xml (aggregated modules, submodules)

<?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>ruoyi</artifactId>
        <groupId>com.ruoyi</groupId>
        <version>4.7.5</version>
        <!-- ../pom.xml是默认值,特意写出来让大家看下配置方法 -->
        <relativePath>../pom.xml</relativePath>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <packaging>jar</packaging>
    <artifactId>ruoyi-admin</artifactId>

    <description>
        web服务入口
    </description>

    <dependencies>

        <!-- SpringBoot集成thymeleaf模板 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>

        <!-- spring-boot-devtools -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional> <!-- 表示依赖不会传递 -->
        </dependency>

        <!-- swagger3-->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-boot-starter</artifactId>
        </dependency>

        <!-- 防止进入swagger页面报类型转换错误,排除3.0.0中的引用,手动增加1.6.2版本 -->
        <dependency>
            <groupId>io.swagger</groupId>
            <artifactId>swagger-models</artifactId>
            <version>1.6.2</version>
        </dependency>

        <!-- Mysql驱动包 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>

        <!-- 核心模块-->
        <dependency>
            <groupId>com.ruoyi</groupId>
            <artifactId>ruoyi-framework</artifactId>
        </dependency>

        <!-- 定时任务-->
        <dependency>
            <groupId>com.ruoyi</groupId>
            <artifactId>ruoyi-quartz</artifactId>
        </dependency>

        <!-- 代码生成-->
        <dependency>
            <groupId>com.ruoyi</groupId>
            <artifactId>ruoyi-generator</artifactId>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>2.1.1.RELEASE</version>
                <configuration>
                    <fork>true</fork> <!-- 如果没有该配置,devtools不会生效 -->
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>3.0.0</version>
                <configuration>
                    <failOnMissingWebXml>false</failOnMissingWebXml>
                    <warName>${project.artifactId}</warName>
                </configuration>
            </plugin>
            <!-- YUI Compressor (CSS/JS压缩)
            <plugin>
                <groupId>net.alchim31.maven</groupId>
                <artifactId>yuicompressor-maven-plugin</artifactId>
                <version>1.5.1</version>
                <executions>
                    <execution>
                        <phase>prepare-package</phase>
                        <goals>
                            <goal>compress</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <encoding>UTF-8</encoding>
                    <jswarn>false</jswarn>
                    <nosuffix>true</nosuffix>
                    <linebreakpos>50000</linebreakpos>
                    <sourceDirectory>src/main/resources/static</sourceDirectory>
                    <force>true</force>
                    <includes>
                        <include>**/*.js</include>
                        <include>**/*.css</include>
                    </includes>
                    <excludes>
                        <exclude>**/*.min.js</exclude>
                        <exclude>**/*.min.css</exclude>
                        <exclude>**/fileinput.js</exclude>
                        <exclude>**/bootstrap-table/**</exclude>
                    </excludes>
                </configuration>
            </plugin> -->
        </plugins>
        <finalName>${project.artifactId}</finalName>
    </build>

</project>

2. pom.xml uses distributionManagement "repository and distributionManagement" snapshotRepository to upload components

The pom.xml of the Maven plugin link-generate-pluginis as follows:

<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/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.hczy.maven.plugin</groupId>
    <artifactId>link-generate-plugin</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>maven-plugin</packaging>

    <dependencies>
        <dependency>
            <groupId>org.apache.maven</groupId>
            <artifactId>maven-plugin-api</artifactId>
            <version>3.6.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.maven.plugin-tools</groupId>
            <artifactId>maven-plugin-annotations</artifactId>
            <version>3.6.0</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>


    <distributionManagement>
        <!-- 上传发布版本构件,不区分普通maven项目和maven插件 -->
        <repository>
        	<!-- id对应settings.xml中server元素下面的id值,用来配置账户名和密码 -->
            <id>admin</id>
            <url>http://192.168.139.133:31743/repository/test-dev/</url>
        </repository>
        <!-- 上传快照版本构件,不区分普通maven项目和maven插件 -->
        <snapshotRepository>
        	<!-- id对应settings.xml中server元素下面的id值,用来配置账户名和密码 -->
            <id>admin</id>
            <url>http://192.168.139.133:31743/repository/test-snapshot/</url>
        </snapshotRepository>
    </distributionManagement>

    <build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-plugin-plugin</artifactId>
            <version>3.6.4</version>
            <configuration>
                <goalPrefix>generate</goalPrefix>
            </configuration>
        </plugin>
    </plugins>
</build>
</project>

3. Use Alibaba Cloud Mirroring in settings.xml

<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
  <!-- 本地仓库绝对路径 -->
  <localRepository>C:\software\MAVEN\apache-maven-3.5.4\mavenRepository</localRepository>

  <mirrors>
    <mirror>
	  <id>local</id>
	  <!-- *代表所有上传下载都能匹配到这个镜像,然后通过这个镜像的url连接到仓库 -->
	  <mirrorOf>*</mirrorOf>
	  <name>阿里云公共仓库</name>
	  <url>https://maven.aliyun.com/repository/public</url>
	</mirror>
  </mirrors>
  
</settings>

3. Use servers, mirrors, profiles in settings.xml

<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
		  
    <localRepository>C:\software\MAVEN\apache-maven-3.5.4\mavenRepository</localRepository>

  <servers>
    <!-- id是给其他位置做对应用的,username是maven私服用户名,而password是密码 -->
	<server>
      <id>admin</id>
      <username>admin</username>
      <password>admin123456</password>
    </server>
	<server>
      <id>central</id>
      <username>admin</username>
      <password>admin123456</password>
    </server>
  </servers>

  <mirrors>
    <mirror>
      <!-- id对应settings.xml中server元素下面的id值,用来配置账户名和密码 -->
	  <id>admin</id>  
	  <url>http://192.168.139.133:31743/repository/test-public/</url>   
	  <mirrorOf>*</mirrorOf>    
    </mirror>
	
  </mirrors>
  
  <profiles>
	<profile>
	  <id>jdk-1.8</id>
	  
	  <activation>
		<jdk>1.8</jdk>
	  </activation>

	  <properties>
		<maven.compiler.source>1.8</maven.compiler.source>
		<maven.compiler.target>1.8</maven.compiler.target>
		<maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
	  </properties>
	</profile>
		
	<profile>
	  <id>admin</id>
	  <!-- 下载普通Maven构件仓库配置 -->
	  <repositories>
		  <repository>
        	  <!-- id对应settings.xml中server元素下面的id值,用来配置账户名和密码 -->
			  <id>central</id>
			  <url>http://192.168.139.133:31743/repository/test-public/</url>
			  <releases>
				  <enabled>true</enabled>
			  </releases>
			  <snapshots>
				  <enabled>true</enabled>
				  <!-- updatePolicy用来配置Maven从远程仓库检查更新的频率,默认值是daily,也就是每天更新一次,而always是每次构建都会检查更新 -->
				  <updatePolicy>never</updatePolicy>
			  </snapshots>
		  </repository>
		</repositories>
	    <!-- 下载Maven插件仓库配置 -->
		<pluginReporitories>
		  <pluginReporitory>
        	  <!-- id对应settings.xml中server元素下面的id值,用来配置账户名和密码 -->
			  <id>central</id>
			  <url>http://192.168.139.133:31743/repository/test-public/</url>
			  <releases>
				  <enabled>true</enabled>
			  </releases>
			  <snapshots>
				  <enabled>true</enabled>
				  <!-- updatePolicy用来配置Maven从远程仓库检查更新的频率,默认值是daily,也就是每天更新一次,而always是每次构建都会检查更新 -->
				  <updatePolicy>never</updatePolicy>
			  </snapshots>
		  </pluginReporitory>
		</pluginReporitories>
	</profile>
  
  </profiles>
  
  <activeProfiles>
	  <activeProfile>jdk-1.8</activeProfile>
	  <activeProfile>admin</activeProfile>
  </activeProfiles>
  
</settings>

Guess you like

Origin blog.csdn.net/qq_42449963/article/details/131614946