Table of contents
- 1. Some thoughts
-
- 1. Why is the Java project that is usually written also called the Maven project?
- 2. Why does the usual Java project directory look like this? Can the directory structure be changed?
- 3. For the Maven project, what can Maven do for us?
- 4. Why do you need a Maven private server, can you not do it?
- 5. Why must execute mvn clean before executing mvn package?
- 6. Why is the maven-compiler-plugin plug-in generally configured in pom.xml, and the values of source and target are set?
- 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?
- 2. Small knowledge points
- 3. Maven Private Server—Nexus
- 四、settings.xml
-
- 1. The reason for putting it here
- 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
- (2) Configuration methods of repositories and pluginRepositories in settings.xml
- (3) Configuration methods of repositories and pluginRepositories in super pom
- (4) Mirror configuration method in settings.xml
- (5) Effective principle
- 3. How to configure the repositories and pluginRepositories in settings.xml to control the download of components?
- 4. Settings.xml location description
- 5. Relevant knowledge points
- 6. Explanation of the role of elements
- Five, pom.xml
-
- 1. The reason for putting it here
- 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?
- 3. Relevant knowledge points
-
- (1) Dependency scope
- (2) Transitive dependency
- (3) Dependency scope and transitive dependency
- (4) Dependency mediation (that is, the same groupId and artifactId, but different version dependencies, which one will be used in the end?)
- (5) Maven properties
- (6) Mechanism for resolving dependencies from warehouses
- (7) Aggregation
- (8) inheritance
- (9) The relationship between aggregation and inheritance
- (10) Life cycle and plug-ins
-
- 1) What is the life cycle
- 2) What are the life cycle stages
- 3) What is a plugin
- 4) What is the plugin goal
- 5) Relationship between life cycle, life cycle phase, plug-in, and plug-in target
- 6) Detailed explanation of the life cycle
- 7) Detailed explanation of plugins and plugin goals
- 8) Parsing process of plug-in groupId and artifactId in pom.xml
- 9) The plug-in prefix parsing process in the mvn command line
- 4. Explanation of the role of elements
-
- (1)modelVersion
- (2)groupId、artifactId、version
- (3)parent
- (4)modules
- (5)packaging
- (6)name
- (7)description
- (8) Several less commonly used project information elements
- (9)properties
- (10)dependencyManagement
- (11)dependencies
- (12)build
- (13)profiles
- (14)distributionManagement》repository
- (15)distributionManagement》snapshotRepository
- (16)repositories》repository
- (17)pluginRepositories》pulginRepository
- 6. Maven plugin
- 7. Example
-
- 1. Use repositories and pluginRepositories in aggregation, inheritance, and pom.xml to download components
- 2. pom.xml uses distributionManagement "repository and distributionManagement" snapshotRepository to upload components
- 3. Use Alibaba Cloud Mirroring in settings.xml
- 3. Use servers, mirrors, profiles in settings.xml
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 RuoYi
in the project ruoyi-admin
, as follows:
Everyone should have written java code. Generally, the main code is placed src/main/java
under the directory, the main configuration file is placed src/main/resources
under the directory, the test code is placed src/test/java
under the directory, the test configuration file is placed src/test/resources
under the directory, and then pom.xml
the 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.model
directory, 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:
Description: A jar package decompilation tool is recommended: jd-gui.ext
When maven executes related commands, for example, mvn clean package
it 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 source
directory instead of src/main/java
below. 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:
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)
project
Project 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
- 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 with
mvn 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:
- default life cycle:
- Site life cycle:
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 package
the command to execute clean
the 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.xml
we 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.netiler
company 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
- 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
- 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/java
directory isgroupId/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, justkms-wiki
replace it with ) in the directorykmswiki
), 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.jar
org.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:
5. Create a host warehouse
First, you need to click the Create Warehouse button, as shown below:
Then select the host warehouse type, as follows:
Then select and enter the corresponding parameters. Version policy
Generally 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 policy
and Release
the Snapshot
other, using To store the corresponding type of jar package, the description information is as follows:
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:
6. Create a proxy warehouse
First, you need to click the Create Warehouse button, as shown below:
Then select the agent warehouse type, as follows:
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:
Currently I have set up a proxy repository test-ali
as follows:
7. Create warehouse group
First, you need to click the Create Warehouse button, as shown below:
Then select the warehouse group type, as follows:
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:
8. Warehouse link
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
(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
(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.model
the 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
(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
(5) Effective principle
-
Find a suitable warehouse:
When downloading dependencies ,settings.xml
the 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
超级Pom
pom.xml
settings.xml
超级Pom
-
After selecting the warehouse, it is necessary to discuss whether
settings.xml
to 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
mirrorOf
element. 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
- 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
-
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:
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:
- Example:
Below is an example of what I use in settings.xml
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 conf
the settings.xml in the directory of the maven installation location is the global configuration file, for example:
5. Relevant knowledge points
6. Explanation of the role of elements
settings.xml element reference:
(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 needls -a
a 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》id
configure 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:
-
The warehouse id in settings.xml matches the id in the server:
-
The mirror id in settings.xml matches the id in the server:
-
The warehouse id in pom.xml matches the id in the server:
-
-
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:
-
What properties can be used in real situations:
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
configuration information for downloading the plug-in jar package is not mentioned above. Here is an example of Nexus built by myself:
-
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:
- System Property Activation
is better explained by directly quoting from the book, as follows:
- OS Environment Activation
is better explained by directly quoting from the book, as follows:
- The presence or absence of the file
is better explained by directly quoting from the book, as follows:
- Activated by default:
It is better to explain the content directly from the book, as follows:
- Command line activation:
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-dev
is the host warehouse of the release version component, test-snapshot
but the host warehouse of the snapshot version component, as follows:
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 version
it -SNAPSHOT
ends 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.xml
elements 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:
According to the real situation, let's take another picture to illustrate:
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 itspire.doc.free-5.2.0.jar
and 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:
-
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:
(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:
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.xml
the ones in Maven属性
will be parsed, and src/main/resources
the resource directories in will not be parsed, but maven插件
the ones used in maven属性
can also be parsed
-
built-in properties
-
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 Pombasedir
, but it does not affect the use
-
Custom properties
We often customize pom under elements, but we can also customize pom through elements under elements inpom.xml
, as follows: Of course , what is shown in the book is to customize Maven properties through elements in , as follows:properties
settings.xml
profile
properties
pom.xml
properties
-
Settings property
-
Java system properties
-
environment variable properties
-
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.
(6) Mechanism for resolving dependencies from warehouses
(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:
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 gav
the coordinates, the submodule can inherit the parent module gv
, and then only artifactId
need to write one. The example is as follows:
For dependencyManagement
dependency 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:
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 necessaryparent>relativePath
to specify the relative position of the parent module in the element of the submodule. ForrelativePath元素
Ruoyi, the default value is../pom.xml
, since Ruoyi’s submodule and parent module are parent-subdirectory relationships, the defaultrelativePath元素
value can be used directly, and we will make it explicit Declare it for everyone to see the specific usage:
(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:
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:
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...
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 package
packaging 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
-
default life cycle
-
site life cycle
-
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:
-
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
-
Built-in bindings for lifecycle and plugin goals:
-
The binding relationship between the clean life cycle phase and the plug-in target
-
The binding relationship between the default life cycle phase and the plug-in target
-
The binding relationship between the site life cycle phase and the plug-in target
-
-
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.
-
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.
8) Parsing process of plug-in groupId and artifactId in pom.xml
We can see that sometimes plugin
it is not necessary to write groupId
the sum artifactId
, which depends on the parsing mechanism of the groupId
sum artifactId
.
groupId: If we omit it groupId
, Maven will think that the plug-in is the official plug-in of Maven, so groupId
it will be considered to be org.apache.maven.plugins
. Of course, there are many official plug-ins of Maven. For example:
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:
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:
9) The plug-in prefix parsing process in the mvn command line
We often use mvn clean package
this method to maven
perform related operations. This method is the life cycle phase of the operation, and the plug-in target is operated through the life cycle phase.
mvn
Then 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 phase
the usage in the above command. Now let’s talk about goal
the usage in the above command. This is the method of calling the plug-in target directly through the command line
Let's talk about goal
the 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:tree
the dependency
plug- tree
in target. How to dependency
find complete plugin coordinates by artifactId prefix gav
. By default, groupId
the default value is assigned to org.apache.maven.plugins
or org.codehaus.mojo
, as org.apache.maven.plugins
an 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.xml
or . Open this The file can see the following content:settings.xml
id
dependency
You can find the real value of artifactId by searching the prefix maven-dependency-plugin
, groupId
and now artifactId
you 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 targetversion
version
gav
tree
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.xml
of the parsing rule file prefixed with the artifactId of our plug-in . maven-metadata-仓库id.xml
This is our own groupId
value, the specific configuration method is:
So we also imitate the configuration method in the local warehouse org/apache/maven/plugins/maven-metadata-central.xml
to configure our own . When using this maven-metadata-仓库id.xml
on 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.xml
maven-metadata-仓库id.xml
4. Explanation of the role of elements
pom.xml element reference:
(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:
- 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
- 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
(4)modules
- Meaning: Declare other modules in the aggregation module to build other modules in a unified way, such as executing
mvn clean deploy
commands 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:
- 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:
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/java
not 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/resources
under the directory, but placedconfig
below, 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:
-
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:
Of course, you can also configure multiple resource directories and enable/disable filtering for them, as follows:
-
Web resource directory filtering
Forweb
projects, there are not onlysrc/main/resources
resource directories, but also another type ofweb
resource filessrc/main/webapp
. In some cases, we also need toweb资源文件
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:
4)plugin
I don’t understand plug-ins either, so I’ll list the frequently-used plug-ins.
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:
(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:
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 isartifactId
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:
Let’s look at the situation where the plugin prefix is specified by us, as follows:
-
Plugin target class, plugin target name, lifecycle phase settings for default bindings:
-
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
- defaultValue: default value, can be used
-
How the properties defined in the plugin target class are defined in the project pom.xml created using:
-
Plugin target class attribute types:
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
- Calculate the number of lines of code:
Link: https://pan.baidu.com/s/1cWmDpuVNu5fXIkDOfhrXyg?pwd=nkxl
Extraction code: nkxl - Generate project address file:
Link: https://pan.baidu.com/s/10UlfU_ugy3N60EbvKAD4yA?pwd=emd9
Extraction code:emd9
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-plugin
is 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>