Detailed explanation of maven aggregation project

This article focuses on these issues:

  1. Maven inheritance
  2. Use IDEA to build Maven parent-child projects
  3. Use IDEA to build Maven aggregation project
  4. The difference between Maven parent-child project and aggregate project

1. Maven inheritance

When Maven was designed, it borrowed the idea of ​​inheritance in Java object-oriented and proposed the idea of ​​POM inheritance.

When a project contains multiple modules, you can create another parent module in the project and declare dependencies in its POM. The POMs of other modules can obtain the declaration of related dependencies by inheriting the POM of the parent module. For the parent module, 其目的是为了消除子模块 POM 中的重复配置,其中不包含有任何实际代码,因此父模块 POM 的打包类型(packaging)必须是 pom.

The tags involved in inheritance are as follows:

insert image description here

2. Idea builds father-son project

1. Create a new parent project, here you can choose springboot normally

2.idea will let you choose the framework that needs to be introduced, here we can directly go to the next step

3. Delete useless files

4. Change the packaging tag of pom.xml to pom

The new springboot project inherits spring-boot-starter-parent by default, and spring-boot-starter-parent provides us with a large number of configurations, many frameworks have version numbers, and many frameworks do not need to declare the version after we inherit No, since it is officially provided, there is no need to worry about the incompatibility between the framework and the framework version.

Here, in order to test parent-child dependency inheritance, I referenced a lang3 package. The complete dependencies are as follows:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.7.10</version>
		<relativePath/>
		<!-- lookup parent from repository -->
	</parent>
	<groupId>com.gzl.cn</groupId>
	<artifactId>paren-demo</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>paren-demo</name>
	<description>paren-demo</description>
	<packaging>pom</packaging>
	<properties>
		<java.version>1.8</java.version>
	</properties>
	<!--依赖管理-->
	<dependencyManagement>
		<dependencies>
			<dependency>
				<groupId>cn.hutool</groupId>
				<artifactId>hutool-all</artifactId>
				<version>5.8.18</version>
			</dependency>
		</dependencies>
	</dependencyManagement>

	<dependencies>
		<dependency>
			<groupId>org.apache.commons</groupId>
			<artifactId>commons-lang3</artifactId>
			<version>3.12.0</version>
		</dependency>
	</dependencies>

</project>

5. Create a new subproject

Remove as much as possible here <relativePath/>, otherwise an exception may be reported! In the POM of the submodule, the groupId and version elements of the current module can be omitted, but this does not mean that the current module does not have groupId and version, and the submodule will implicitly inherit these two elements from the parent module, that is, controlled by the parent module The company organization id and version of the submodule, which simplifies the configuration of the POM.

6. Now there is a problem that the project is not recognized as a maven project by idea
(1) First click Help on the far left of the toolbar and then click Find Action; or use the shortcut key Ctrl+Shift+A
(2) Then enter maven in the input box projects , a Add Maven Projects option will pop up, click it, and the pop-up window as shown below will pop up

(3) Finally, select the pom.xml of this project and click OK to solve it!

Observe as follows:

3. Inheritable POM elements

4. Maven Aggregation

The above project is just a new sub-project. In the actual development process, the projects we come into contact with are generally composed of multiple modules. When building a project, it would be very troublesome to build modules one by one every time. Maven's aggregation function solves this problem very well.

When using the Maven aggregation function to build a project, you need to create an additional aggregation module in the project, and then use this module to build all the modules of the entire project. The aggregation module is just a tool to help aggregate other modules, without any real content itself, so there is only one POM file in the aggregation module, unlike other modules that contain multiple directories such as src/main/java, src/test/java, etc. .

Similar to the parent module, the packaging method of the aggregation module is also pom. Users can add the directory path of the module to be aggregated through the module sub-element under modules in their POM.

<modules>
	<module>user-service</module>
</modules>

5. Idea builds aggregation project

Still take the above project as an example, this is what it looks like before aggregation: paren-demo and user-service are at the same level

Modify the configuration of the Root module POM as follows:

At this time, when you clean install the parent project, you will find that it will be built together with the sub-project

When the aggregation module is built, Maven will first parse the POM of the aggregation module, analyze the modules to be built, and calculate the construction order according to the relationship between these modules, and then build each module in turn according to this order.

After the build is completed, the output is a summary report of the project build, which includes information such as whether the build of each module is successful or not, the time spent on the build, and the time spent on the entire build.

Six, the relationship between inheritance and aggregation

The purpose of Maven's inheritance and aggregation is different. The purpose of inheritance is to eliminate repeated configuration in POM, and the purpose of aggregation is to facilitate and quickly build projects.

  • For the parent module in inheritance, it doesn't know which modules inherit it, but all submodules know who their parent module is.
  • For the aggregated module, it knows which modules are aggregated, but those aggregated modules don't know the existence of the aggregated module at all.

The two still have some similarities in structure and form. The most intuitive thing is that both are packaged in pom, and both have no actual code content except POM.

Note: Aggregation can be used without inheritance, and inheritance can be used without aggregation, and there is no dependency between the two!

In actual development, aggregation and inheritance are generally used together. Using idea can be quickly created, as follows:

Although creating a maven project in this way can save us the time to modify the pom, we still need to manually modify the springboot startup class and add the resources folder.

7. dependency management

We know that submodules can obtain all dependencies declared in the parent module through inheritance. Although this avoids repeated dependency declarations in each submodule POM, it is also very likely to introduce some unnecessary dependencies into submodules. For this reason, Maven introduced dependencyManagement to manage dependencies.

Maven can manage dependencies through the dependencyManagement element, which has the following two major features:

  • 在该元素下声明的依赖不会实际引入到模块中, it will be imported into the module only if the dependency is also declared under the dependencies element.
  • 该元素能够约束 dependencies 下依赖的使用, that is, if the dependencies declared by dependencies do not specify a version, the version specified in dependencyManagement will be used; otherwise, the version in dependencyManagement will be overwritten.

In the actual development process, dependencyManagement is rarely used alone, usually it needs to be used in conjunction with Maven inheritance or dependency scope import to show its advantages.

For example, use the following pom in the parent dependency:

<dependencyManagement>
	<dependencies>
		<dependency>
			<groupId>cn.hutool</groupId>
			<artifactId>hutool-all</artifactId>
			<version>5.8.18</version>
		</dependency>
	</dependencies>
</dependencyManagement>

At this time, the submodule can only import the framework through groupId and artifactId. Version and scope can be omitted.

<dependencies>
	<dependency>
		<groupId>cn.hutool</groupId>
		<artifactId>hutool-all</artifactId>
	</dependency>
</dependencies>

Using this dependency management mechanism does not seem to reduce the POM configuration too much, but we still recommend it for two main reasons:

  • Using dependencyManagement to declare dependencies in the parent module can unify the version of dependencies in the project. Submodules do not need to declare versions, and there will be no inconsistencies in multiple submodules using the same dependency version, reducing the probability of dependency conflicts.
  • The dependencies declared by dependencyManagement will not be actually introduced, and any dependencies required by submodules will be introduced by themselves, which increases flexibility and avoids introducing unnecessary dependencies

The import dependency range can only be valid when used in conjunction with the dependencyManagement element, and its function is to import and merge the dependencyManagement configuration in the target pom.xml into the dependencyManagement of the current pom.xml.

If you don’t know much about spring-boot-dependencies, you can read this article: https://blog.csdn.net/weixin_43888891/article/details/130520345

<dependencyManagement>
	 <dependencies>
		<dependency>
			 <groupId>org.springframework.boot</groupId>
			 <artifactId>spring-boot-dependencies</artifactId>
			 <version>2.7.10</version>
			 <type>pom</type>
			 <scope>import</scope>
		 </dependency>
	</dependencies>
</dependencyManagement>

In the above configuration, due to the particularity of the scope of import dependencies, it generally points to the module whose packaging type is pom, so the value of the type element is generally pom.

For example, there are many projects managed by dependencyManagement in spring-boot-dependencies, and it will import all dependency management in dependencyManagement into the current project.

八、pluginManagement

The principle of the pluginManagement element is very similar to that of the dependencyManagement element. In the pluginManagement element, plug-ins and plug-in configurations can be declared, but the actual plug-in invocation behavior will not occur. Only the real plugin element is configured in the POM, and its groupId and artifactId are the same as the pluginManagement element The configuration of the pluginManagement element will only affect the actual plugin behavior when the plugins configured in .

When the same plugin exists in multiple modules in a project, the plugin configuration should be moved to the pluginManagement element of the parent module. Even if each module has different specific configurations for the same plugin, the pluginManagement element should be used in the parent module to declare the plugin version uniformly.

Spring-boot-dependencies provides us with a large number of plug-in version management, which is why we sometimes do not need to declare the version number at all when referencing plug-ins in the springboot project:

The default configuration of springboot parent pom is as follows:

  • delimiter: It is to change the form of variable value, as mentioned above.
  • propertiesEncoding: is the character encoding

Then I declared the maven-resources-plugin plugin in my project:

<plugin>
	<groupId>org.apache.maven.plugins</groupId>
	<artifactId>maven-resources-plugin</artifactId>
	<version>3.2.0</version>
	<configuration>
	  <nonFilteredFileExtensions>
		 <!--不应用过滤的其他文件扩展名(已定义的有:jpg, jpeg, gif, bmp, png)-->
		  <nonFilteredFileExtension>xls</nonFilteredFileExtension>
		  <nonFilteredFileExtension>xlsx</nonFilteredFileExtension>
	   </nonFilteredFileExtensions>
	</configuration>
</plugin>

One thing to note here is that springboot sets the maven-resources-plugin in the pluginManagement of the parent pom, and we declare the maven-resources-plugin in the project. In the end, what takes effect is the parent pom+ the configuration we declared:

mvn help:effective-pomYou can view the effective pom through the command

Guess you like

Origin blog.csdn.net/weixin_43888891/article/details/130732237