文章目录
- 前言
- 一、dependencyManagement
- 一、dependencies传递规则
- 二、引用顺序统一声明
- 三、maven插件默认行为声明
- 四、动态server.name
前言
系统整理一下用到的maven继承关系
一、dependencyManagement
版本控制
<properties>
<!--jar版本定义 -->
<spring-boot.version>3.2.1</spring-boot.version>
</properties>
<dependencyManagement>
<dependencies>
<!-- spring boot 依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
下游项目直接引用,无需声明版本,如果要更改版本,只需要在下游项目的properties 覆盖对应的把版本即可。
<properties>
<!--覆盖父pom定义的版本 -->
<spring-boot.version>3.2.0</spring-boot.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
一、dependencies传递规则
父pom引用的jar 子pom引用后直接包含父pom中的jar。
scope
作用:
在Maven中,依赖的作用域(scope)决定了这个依赖将在项目的哪个阶段以及如何被使用。Maven的依赖作用域包括以下几种:
-
compile: 这是默认作用域,用于项目的编译阶段。在这个作用域下的依赖对于编译和运行时都是必需的,并且默认情况下也会被包括在发布的项目中。此作用域的依赖在编译路径(classpath)上可用,并且也会传递给依赖当前项目的其他项目。
-
provided: 表示依赖在编译时和测试时需要,但在运行时不需要,因为运行时环境已经提供了这个依赖(比如Servlet API或者一些应用服务器中的API)。这类依赖在编译路径上可用,但不会被打包到最终的打包文件中,也不会被传递。
-
runtime: 表示依赖在运行和测试系统的时候需要,但在编译主代码时不需要。它在运行时和测试路径上可用,但不在编译路径上。
-
test: 依赖仅在测试编译和执行的测试时需要。这些依赖不会被打包,也不会在正常的编译过程中使用。
-
system: 类似于
provided
作用域,但是你必须提供JAR文件的路径。它不推荐使用,因为会使构建不可移植。 -
import(仅适用于
<dependencyManagement>
中): 这个作用域不是用于依赖项本身,而是用于pom
类型的依赖,它表示从另一个POM文件导入依赖管理的配置。
通过选择正确的依赖作用域,你可以确保项目仅包含必要的依赖,同时避免在运行时环境中可能出现的冲突。以下是一个在POM文件中声明依赖作用域的例子:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.3.3</version>
<scope>compile</scope> <!-- 可以是compile, provided, runtime, test, system -->
</dependency>
每个依赖作用域都有其特定的使用场景,合理地使用它们可以使项目构建过程更加高效和精确。
案例:
父pom 引用therapi-runtime-javadoc-scribe
时,无法向下游传递。
该jar定义了<scope>runtime</scope>
,只能向下游传递一次,所以当父pom需要再向下游传递时,需要显式声明一下scope
<dependency>
<groupId>com.github.therapi</groupId>
<artifactId>therapi-runtime-javadoc-scribe</artifactId>
<!-- 覆盖原scope机制 传递下游项目时无需再引用一次-->
<scope>runtime</scope>
</dependency>
二、引用顺序统一声明
mapstruct 编译需要实体类有get set,当pom引用先引用mapstruct后引用lombok,编译时无法获取到get set 导致无法正确赋值。
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven.compiler.plugin.version}</version>
<configuration>
<encoding>${project.build.sourceEncoding}</encoding>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.source}</target>
<annotationProcessorPaths>
<path>
<groupId>com.github.therapi</groupId>
<artifactId>therapi-runtime-javadoc-scribe</artifactId>
<version>${therapi.javadoc.version}</version>
</path>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</path>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${mapstruct.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<version>${maven.deploy.plugin.version}</version>
<configuration>
<skip>${maven.deploy.skip}</skip>
</configuration>
</plugin>
</plugins>
三、maven插件默认行为声明
下面代码统一定义了maven打包方式(thin jar)
<pluginManagement>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
<configuration>
<finalName>${project.build.finalName}</finalName>
<layers>
<enabled>true</enabled>
</layers>
<includes>
<include>
<groupId>nothing</groupId>
<artifactId>nothing</artifactId>
</include>
</includes>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>../lib</outputDirectory>
<excludeTransitive>false</excludeTransitive>
<stripVersion>false</stripVersion>
<!--complie和runtime的包都打到lib中,否则可能lib缺包-->
<includeScope>runtime</includeScope>
</configuration>
</execution>
</executions>
</plugin>
<!-- 预定义assembly plugin,以便子项目可以覆盖 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<!-- 默认配置,子POM可以覆盖 -->
</configuration>
</plugin>
</plugins>
</pluginManagement>
下游pom引用:
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
</plugin>
</plugins>
</build>
如果下游pom想要覆盖父pom默认设置,可以重写对应的节点进行设置。
下游项目如果想要fat jar时,需要覆盖特定设置maven-assembly-plugin
如下:
<build>
<plugins>
<!-- 覆盖 assembly 插件配置 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<archive>
<manifest>
<mainClass>com.your.main.Class</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
四、动态server.name
直接引用artifactId作为server.name,同理其他配置文件配置也可以从pom中定义@@
获取
spring:
application:
name: @project.artifactId@
maven需要以下配置使@@
生效。
<name>${project.artifactId}</name>
<build>
<finalName>${project.name}</finalName>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
在Maven中,resources
是指项目中除了Java源代码之外包含的其他文件,如配置文件、属性文件、静态资源等。在构建过程中,这些资源文件会从项目的源目录复制到输出目录,通常是target/classes
,从而能够与编译后的.class
文件一起打包到最终的JAR、WAR或EAR文件中。
Maven通过maven-resources-plugin
来处理资源文件的复制。在项目的pom.xml
文件中,你可以使用<resources>
元素来定义资源处理的细节。例如,你可以指定哪些文件或文件夹应该被包含或排除,以及使用过滤器替换资源文件中的某些值。
以下是<resources>
元素的一个基本示例:
<project>
...
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<excludes>
<exclude>**/*.ignore</exclude>
</excludes>
</resource>
</resources>
...
</build>
...
</project>
在这个例子中:
<directory>
指定了资源文件所在的目录。<filtering>
开启或关闭过滤器。当设置为true
时,可以在资源文件中使用Maven属性,这些属性在复制过程中会被实际的值替换。<includes>
和<excludes>
定义了哪些文件应该被包含或排除。它们使用通配符表达式来匹配文件名。
Maven的过滤特性非常有用,比如在构建不同环境(开发、测试、生产)的配置文件时替换不同的数据库连接字符串或API密钥。
如果你没有在pom.xml
中明确指定资源,Maven将默认包含src/main/resources
目录下的所有文件,并将它们复制到target/classes
目录。
Maven资源处理是构建过程中的一个重要方面,因为它确保了所有非代码文件都能正确地打包并与你的应用程序一起分发。