前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >Maven详解

Maven详解

作者头像
冬天vs不冷
发布2025-01-21 10:19:45
发布2025-01-21 10:19:45
10500
代码可运行
举报
文章被收录于专栏:springbootspringboot
运行总次数:0
代码可运行

1、Maven核心概念

1.1、坐标

1)数学中的坐标

使用 x、y、z 三个『向量』作为空间的坐标系,可以在『空间』中唯一的定位到一个『点』

2)Maven中的坐标

  • 使用三个向量在Maven的仓库中唯一的定位到一个jar包
    • groupId公司或组织的 id
    • artifactId一个项目或者是项目中的一个模块的 id(模块的名称、工程名)
    • version版本号

1.2、POM

超级POM

  • Maven 在构建过程中有很多默认的设定。例如:源文件存放的目录、测试源文件存放的目录、构建输出的目录……等等
  • 但是其实这些要素也都是被 Maven 定义过的。定义的位置就是:超级 POM
  • 所以我们自己的 POM 即使没有明确指定一个父工程(父 POM),其实也默认继承了超级 POM。就好比一个 Java 类默认继承了 Object 类
代码语言:javascript
代码运行次数:0
复制
<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>

父 POM

和 Java 类一样,POM 之间其实也是单继承的。如果我们给一个 POM 指定了父 POM,那么继承关系如下图所示:

当前POM

  • POM:Project Object Model,项目对象模型
  • 当前工程配置的pom配置文件
代码语言:javascript
代码运行次数:0
复制
<!-- 当前Maven工程的坐标 -->
<groupId>com.atguigu.maven</groupId>
<artifactId>pro01-maven-java</artifactId>
<version>1.0-SNAPSHOT</version>

<!-- 当前Maven工程的打包方式,可选值有下面三种: -->
<!-- jar:表示这个工程是一个Java工程  -->
<!-- war:表示这个工程是一个Web工程 -->
<!-- pom:表示这个工程是“管理其他工程”的工程 -->
<packaging>jar</packaging>

<name>pro01-maven-java</name>
<url>http://maven.apache.org</url>

<properties>
<!-- 工程构建过程中读取源码时使用的字符集 -->
  <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<!-- 当前工程所依赖的jar包 -->
<dependencies>
<!-- 使用dependency配置一个具体的依赖 -->
  <dependency>
 <!-- 在dependency标签内使用具体的坐标依赖我们需要的一个jar包 -->
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
 <!-- scope标签配置依赖的范围 -->
    <scope>test</scope>
  </dependency>
</dependencies>

有效 POM

  • 在 POM 的继承关系中,子 POM 可以覆盖父 POM 中的配置
  • 如果子 POM 没有覆盖,那么父 POM 中的配置将会被继承
  • 按照这个规则,继承关系中的所有 POM 叠加到一起,就得到了一个最终生效的 POM
  • 执行命令:mvn help:effective-pom

综上所述,平时我们使用和配置的 POM 其实大致是由四个层次组成的:

  • 超级 POM:所有 POM 默认继承,只是有直接和间接之分。
  • 父 POM:这一层可能没有,可能有一层,也可能有很多层。
  • 当前 pom.xml 配置的 POM:我们最多关注和最多使用的一层。
  • 有效 POM:隐含的一层,但是实际上真正生效的一层。

1.3、约定的目录结构

另外还有一个 target 目录专门存放构建操作输出的结果

2、依赖管理

2.1、依赖范围

  • 标签的位置:dependencies(依赖)/dependency(依赖项)/scope(范围)
  • 标签的可选值:compile/test/provided/system/runtime/import

作用域scope

编译

测试

运行

打包

举例

compile(默认)

spring-core

test

junit

provided

sevlet-api、lombok

runtime

jdbc驱动

system

本地包

  • compile:编译依赖范围
    • 如果引用的依赖没有指定scope,默认会使用该依赖范围
    • 对于编译、测试、运行三种classpath都有效
  • test:测试依赖范围
    • 只对测试期classpath有效
    • 典型的例子是junit,它只有在编译测试代码及运行测试的时候才需要
  • provided:已提供依赖范围
    • 对于编译和测试classpath有效,但在运行时无效
    • 典型的例子是servlet-api,编译和测试项目的时候需要该依赖,但运行项目的时候,容器已提供
  • runtime:运行时依赖范围
    • 对于测试和运行class-path有效,但在编译主代码时无效
    • 典型的例子是JDBC驱动实现,项目主代码的编译只需要JDK提供的JDBC接口,只有在执行运行项目的时候才需要实现接口的具体JDBC驱动
  • system:系统依赖范围
    • 依赖项不会从maven仓库获取,而是从本地系统文件拿,一定要配合<systemPath>使用
    • project.basedir指定的是pom.xml文件所在的目录,这个应该是pom的属性
    • 打包插件配置<includeSystemScope>true</includeSystemScope>,否则可执行jar中没有<scope>system</scope>的依赖
代码语言:javascript
代码运行次数:0
复制
<dependency>
    <groupId>com.xc.maven</groupId>
    <artifactId>xc-maven-test</artifactId>
    <version>1.0-SNAPSHOT</version>
    <systemPath>${project.basedir}/src/main/resources/lib/open-api-sdk-2.0.jar</systemPath>
    <scope>system</scope>
</dependency>
<!--配合打包插件配置-->
<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
                <includeSystemScope>true</includeSystemScope>
            </configuration>
        </plugin>
    </plugins>
</build>

2.2、解决pom单继承问题

<type>pom</type>

用法一:

  • 当一个父pom中的dependencyManagement标签中需要导入另一个pom中的dependencyManagement的时候
  • 必须同时使用<scope>import</scope><type>pom</type>
代码语言:javascript
代码运行次数:0
复制
<dependencyManagement>
     <dependencies>
         <dependency>
             <!-- Import dependency management from Spring Boot -->
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-dependencies</artifactId>
             <version>2.0.1.BUILD-SNAPSHOT</version>
             <type>pom</type>
             <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>
  • 该pom中dependencyManagement就会包含导入的spring-boot-dependencies中的所有dependencyManagement
  • 这是为了解决pom类型的父工程单继承的问题,通过导入,可以导入各种其他父工程的dependencyManagement
  • dependencyManagement只在父工程(即pom类型的maven工程)中声明,在子工程中定义无需声明版本从而生效

用法二:

  • 当需要把一些依赖定义到一个pom工程中,但是由于maven单继承机制,子工程又想通过依赖引入该pom工程中的所有依赖
  • 只需要添加<type>pom</type>
代码语言:javascript
代码运行次数:0
复制
<dependencies>
  <dependency>
      <groupId>org.sonatype.mavenbook</groupId>
	     <artifactId>persistence-deps</artifactId>
	     <version>1.0</version>
      <type>pom</type>
    </dependency> 
</dependencies>
  • 为了解决子工程单继承的问题,通过<type>pom</type>可以依赖于其他的pom父工程,从而将pom工程中的依赖都传递过来
  • type 默认是jar,依赖jar工程时可以不写type标签

2.3、可选依赖

代码语言:javascript
代码运行次数:0
复制
<!--热部署 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-devtools</artifactId>
    <scope>runtime</scope>
    <optional>true</optional>
</dependency>
  • A依赖上述jar,A可以实现热部署,其实对于A来说,可选依赖没有作用
  • 如果有B依赖A,此时热部署依赖是隐藏的,B看不到
  • 一句话,阻止依赖传递

2.4、依赖的传递性

传递的原则

  • 在 A 依赖 B,B 依赖 C 的前提下,C 是否能够传递到 A,取决于 B 依赖 C 时使用的依赖范围
    • B 依赖 C 时使用 compile 范围:可以传递
    • B 依赖 C 时使用 test 或 provided 范围:不能传递

举例:

一个工程,三个模块,install到本地仓库

第一步:project1依赖project2

代码语言:javascript
代码运行次数:0
复制
<dependencies>
    <dependency>
        <groupId>com.xc</groupId>
        <artifactId>project2</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>
</dependencies>

第二步:project2依赖project3

代码语言:javascript
代码运行次数:0
复制
<dependencies>
    <dependency>
        <groupId>com.xc</groupId>
        <artifactId>project3</artifactId>
        <version>1.0-SNAPSHOT</version>
        <scope>compile</scope>
    </dependency>
</dependencies>

第三步:查看project1所有的依赖

project2直接依赖,project3间接依赖

修改第二步,project2依赖project3的范围

代码语言:javascript
代码运行次数:0
复制
<dependencies>
    <dependency>
        <groupId>com.xc</groupId>
        <artifactId>project3</artifactId>
        <version>1.0-SNAPSHOT</version>
        <scope>test</scope>
    </dependency>
</dependencies>

第三步:查看project1所有的依赖

此时只有直接依赖project2

2.5、版本优先级

首要判断:最短路径优先

在下图的例子中,对模块 pro25-module-a 来说,Maven 会采纳 1.2.12 版本

再者判断:路径相同时先声明者优先

此时 Maven 采纳哪个版本,取决于在 pro29-module-x 中,对 pro30-module-y 和 pro31-module-z 两个模块的依赖哪一个先声明

2.6、依赖的排除

概念

  • 当 A 依赖 B,B 依赖 C 而且 C 可以传递到 A 的时候,A 不想要 C,需要在 A 里面把 C 排除掉
  • 而往往这种情况都是为了避免 jar 包之间的冲突

配置方式

project1依赖project2,project2依赖proejct3,依赖默认范围compile情况下,project1排查project3

1)前两步如依赖传递的第一步和第二步 2)第三步在A依赖B的时候排除C

代码语言:javascript
代码运行次数:0
复制
<dependency>
    <groupId>com.xc</groupId>
    <artifactId>project2</artifactId>
    <version>1.0-SNAPSHOT</version>
    <scope>compile</scope>
    <!-- 使用excludes标签配置依赖的排除	-->
    <exclusions>
        <!-- 在exclude标签中配置一个具体的排除 -->
        <exclusion>
            <!-- 指定要排除的依赖的坐标(不需要写version) -->
            <groupId>com.xc</groupId>
            <artifactId>project3</artifactId>
        </exclusion>
    </exclusions>
</dependency>

3)查看project1和project2的所有依赖

  • project1间接依赖的project3已移除
  • project2对project3的依赖没有变

2.7、版本号

版本号组成

  • <主版本>.<次版本>.<增量版本>-<里程碑版本>
    • 主版本: 表示项目的重大架构变化。如struts2和struts1采用不同的架构
    • 次版本: 较大范围功能增加和变化,及bug修复,并且不涉及到架构变化的
    • 增量版本:表示重大bug的修复,如果发现项目发布之后,出现影响功能的bug,及时修复,则应该是增量版本的变化
    • 里程碑版本:往往表示某个版本的里程碑,经常见到snapshot,另外还有alpha、beta,比如:1.0-SNAPSHOT、3.0-alpha-1
  • 比如1.2.1、1.7、1.0-SNAPSHOT、1.1-release​、2.3-alpha等的version
  • 一般情况下,主版本和次版本会一直存在,增量版本和里程碑版本相对少

  • snapshot表示快照版,它不是个稳定版本,属于开发过程中使用的版本
  • 当一个项目开发完成后,就会进入测试版本,而测试版本一般会分为内部测试alpha版外部测试beta版两种
  • 当测试通过后,将会进入正式版本,大部分的正式版是啥也不带,就一个单纯的版本号,比如1.0、1.7.1等。也有个别的是这些rcfinalstablereleasega

3、继承

概念

Maven工程之间,A 工程继承 B 工程。本质上是 A 工程的 pom.xml 中的配置继承了 B 工程中 pom.xml 的配置

创建父工程

  • 工程名称:pro-maven-parent
  • 工程创建好之后,要修改它的打包方式
  • 只有打包方式为 pom 的 Maven 工程能够管理其他 Maven 工程
  • 打包方式为 pom 的 Maven 工程中不写业务代码,它是专门管理其他 Maven 工程的工程
代码语言:javascript
代码运行次数:0
复制
<groupId>com.xc.maven</groupId>
<artifactId>pro-maven-parent</artifactId>
<version>1.0-SNAPSHOT</version>

<!-- 当前工程作为父工程,它要去管理子工程,所以打包方式必须是 pom -->
<packaging>pom</packaging>

创建子工程

如果子工程坐标中的groupId和version与父工程一致,那么可以省略

代码语言:javascript
代码运行次数:0
复制
<!-- 使用parent标签指定当前工程的父工程 -->
<parent>
	<!-- 父工程的坐标 -->
	<groupId>com.xc.maven</groupId>
	<artifactId>pro-maven-parent</artifactId>
	<version>1.0-SNAPSHOT</version>
</parent>

<!-- 子工程的坐标 -->
<!-- <groupId>com.atguigu.maven</groupId> -->
<artifactId>pro01-maven-module</artifactId>
<!-- <version>1.0-SNAPSHOT</version> -->

父工程中配置依赖的统一管理

被管理的依赖并没有真正被引入到工程

代码语言:javascript
代码运行次数:0
复制
<!-- 使用dependencyManagement标签配置对依赖的管理 -->
<dependencyManagement>
	<dependencies>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-core</artifactId>
			<version>4.0.0.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-beans</artifactId>
			<version>4.0.0.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>4.0.0.RELEASE</version>
		</dependency>
	</dependencies>
</dependencyManagement>

子工程中引用那些被父工程管理的依赖

  • 子工程引用父工程中的依赖信息时,可以把版本号去掉
  • 把版本号去掉就表示子工程中这个依赖的版本由父工程决定
代码语言:javascript
代码运行次数:0
复制
<!-- 具体来说是由父工程的dependencyManagement来决定。 -->
<dependencies>
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-core</artifactId>
	</dependency>
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-beans</artifactId>
	</dependency>
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-context</artifactId>
	</dependency>
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-expression</artifactId>
	</dependency>
</dependencies>

在父工程中声明自定义属性

通过自定义属性,统一指定Spring的版本

代码语言:javascript
代码运行次数:0
复制
<properties>
	<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
	<!-- 自定义标签,维护Spring版本数据 -->
	<my.spring.version>4.3.6.RELEASE</my.spring.version>
</properties>

在需要的地方使用${}的形式来引用自定义的属性名

代码语言:javascript
代码运行次数:0
复制
<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-core</artifactId>
	<version>${my.spring.version}</version>
</dependency>

4、聚合

使用一个“总工程”将各个“模块工程”汇集起来,作为一个整体对应完整的项目

好处

  • 一键执行 Maven 命令:很多构建命令都可以在“总工程”中一键执行
    • Maven 要求有父工程时先安装父工程
    • 有依赖的工程时,先安装被依赖的工程
  • 配置聚合之后,各个模块工程会在总工程中展示一个列表,让项目中的各个模块一目了然

聚合的配置

在总工程中配置 modules 即可

代码语言:javascript
代码运行次数:0
复制
<modules>  
	<module>pro01-maven-module</module>
	<module>pro02-maven-module</module>
	<module>pro03-maven-module</module>
</modules>

5、其他核心概念

5.1、生命周期

作用

为了让构建过程自动化完成,Maven 设定了三个生命周期,生命周期中的每一个环节对应构建过程中的一个操作

三个生命周期

生命周期名称

作用

各个环节

Clean

清理操作相关

pre-cleancleanpost-clean

Site

生成站点相关

pre-sitesitepost-sitedeploy-site

Default

主要构建过程

validategenerate-sourcesprocess-sourcesgenerate-resourcesprocess-resources 复制并处理资源文件,至目标目录,准备打包compile 编译项目 main 目录下的源代码process-classesgenerate-test-sourcesprocess-test-sourcesgenerate-test-resourcesprocess-test-resources复制并处理资源文件,至目标测试目录test-compile编译测试源代码process-test-classestest 使用合适的单元测试框架运行测试。这些测试代码不会被打包或部署prepare-packagepackage 接受编译好的代码,打包成可发布的格式pre-integration-testpost-integration-testverifyinstall 将包安装至本地仓库,以让其它项目依赖deploy 将最终的包复制到远程的仓库,以让其它开发人员共享;或者部署到服务器上运行

特点

  • 前面三个生命周期彼此是独立的
  • 在任何一个生命周期内部执行任何一个具体环节的操作都是从本周期最初的位置开始执行,直到指定的地方

5.2、插件和目标

插件

  • Maven 的核心程序仅仅负责宏观调度,不做具体工作
  • 具体工作都是由 Maven 插件完成的
  • 例如:编译就是由 maven-compiler-plugin-3.1.jar 插件来执行的

目标

  • 一个插件可以对应多个目标,而每一个目标都和生命周期中的某一个环节对应
  • Default 生命周期中有 compile 和 test-compile 两个和编译相关的环节,这两个环节对应 compile 和 test-compile 两个目标,而这两个目标都是由 maven-compiler-plugin-3.1.jar 插件来执行的

5.3、生成微服务可运行 jar 包

  • 应用微服务打包插件,可以以 SpringBoot 微服务形式直接运行的 jar 包包括:
    • 当前微服务本身代码
    • 当前微服务所依赖的 jar 包
    • 内置 Tomcat(Servlet 容器)
    • 与 jar 包可以通过 java -jar 方式直接启动相关的配置
  • 没有如下插件,打包默认只生产依赖jar,不会生产可执行jar
代码语言:javascript
代码运行次数:0
复制
<!-- build 标签:用来配置对构建过程的定制 -->
<build>
    <!-- plugins 标签:定制化构建过程中所使用到的插件 -->
	<plugins>
        <!-- plugin 标签:一个具体插件 -->
		<plugin>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-maven-plugin</artifactId>
		</plugin>
	</plugins>
</build>

举例1

pom文件:

代码语言:javascript
代码运行次数:0
复制
...
    <groupId>com.xc</groupId>
    <artifactId>springboot-mybatis</artifactId>
    <version>1.0-SNAPSHOT</version>
...

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

打包结果:

  • repackage 功能的作用,分为两步:
    • 第一步:首先 mvnpackage 命令 对项目进行打包,打成一个 jar,这个 jar 就是一个普通的 jar,可以被其他项目依赖,但是不可以被执行
    • 第二步:然后repackage 命令,对第一步 打包成的 jar 进行再次打包,将之打成一个 可执行 jar ,通过将第一步打成的 jar重命名为 *.original 文件
  • springboot-mybatis-1.0-SNAPSHOT.jar
    • 命名: artifactId + 版本号,用“-”连接
    • 可以使用java -jar xxx直接运行的服务,里面包含依赖的jar
  • springboot-mybatis-1.0-SNAPSHOT.jar.original
    • 去掉后缀.original则是可以被其他项目依赖的jar

举例2

pom文件:

代码语言:javascript
代码运行次数:0
复制
...
    <groupId>com.xc</groupId>
    <artifactId>springboot-mybatis</artifactId>
    <version>1.0-SNAPSHOT</version>
...

    <build>
        <finalName>my-mybatis</finalName>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <classifier>exec</classifier>
                    <skip>false</skip>
                </configuration>
            </plugin>
        </plugins>
    </build>

打包结果:

  • <finalName>标签:设置打包的名称,不再使用artifactId + 版本号方式
  • <classifier>标签:设置可运行服务jar的后缀
    • 因为可运行jar有了后缀
    • 所有依赖jar就不会重名,也就不用添加后缀.original
  • <skip>标签:mavn执行插件选择是否跳过,默认false,true则不执行当前插件

5.4、<resources>标签

不写<resources>标签

  • src/main/java下非java文件都不会编译 (target当中的classes和打出的包解压BOOT-INF当中的classes都找不到)
  • src/main/resources下的文件都会被编译 (target当中的classes和打出的包解压BOOT-INF当中的classes都可以找到)

<resources>标签只设置src/main/java

  • 假如代码中有xml想加载编译,添加如下
代码语言:javascript
代码运行次数:0
复制
<build>
    <resources>
        <resource>
            <directory>src/main/java</directory>
            <filtering>true</filtering>
            <includes>
                <include>**/*.xml</include>
            </includes>
        </resource>
    </resources>
</build>
  • 此时src/main/java中的xml会编译,但是src/main/resource中的所有资源都没有加载
  • 可以理解为:
    • 不加<resource>则默认只加载resource文件
    • 添加<resource>则是加哪个路径,只加载哪个路径的文件

最终方案

  • <filtering>标签:默认值为false。指定打包时的配置文件其中${}引用会换成直接引用
  • 如此,java和resources下需要的资源都会加载
代码语言:javascript
代码运行次数:0
复制
<build>
	<resources>
		<resource>
			<directory>src/main/java</directory>
			<filtering>true</filtering>
            <includes>
                <include>**/*.xml</include>
            </includes>
        </resource>
		<resource>
			<directory>src/main/resources</directory>
			<filtering>true</filtering>
        </resource>
	</resources>
</build>	

6、Maven 自定义插件

1、设定打包方式

代码语言:javascript
代码运行次数:0
复制
<packaging>maven-plugin</packaging>

2、引入依赖

核心依赖

代码语言:javascript
代码运行次数:0
复制
<dependency>
    <groupId>org.apache.maven</groupId>
    <artifactId>maven-plugin-api</artifactId>
    <version>3.5.2</version>
</dependency>

使用注解标注执行目标名称

代码语言:javascript
代码运行次数:0
复制
<dependency>
    <groupId>org.apache.maven.plugin-tools</groupId>
    <artifactId>maven-plugin-annotations</artifactId>
    <version>3.5.2</version>
</dependency>

3、创建 Mojo 类

代码语言:javascript
代码运行次数:0
复制
@Mojo(name = "sayHello")//执行目标名称
public class MyHelloPlugin extends AbstractMojo {
    @Override
    public void execute() throws MojoExecutionException, MojoFailureException {
        getLog().info("---> hello word my maven plugin <---");
    }
}

4、配置build

代码语言:javascript
代码运行次数:0
复制
<build>
    <plugins>
        <plugin>
            <groupId>com.xc</groupId>
            <artifactId>hello-maven-plugin</artifactId>
            <version>1.0-SNAPSHOT</version>
            <executions>
                <execution>
                    <!-- 指定唯一标识 -->
                    <id>hello1</id>
                    <!-- 指定和目标关联的生命周期阶段 -->
                    <phase>validate</phase>
                    <!-- 关联指定生命周期的目标 -->
                    <goals>
                        <!-- goals 标签中可以配置多个 goal 标签,表示一个生命周期环节可以对应当前插件的多个目标 -->
                        <goal>sayHello</goal>
                    </goals>
                </execution>
                <execution>
                    <id>hello2</id>
                    <phase>compile</phase>
                    <goals>
                        <goal>sayHello</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

5、执行compile,绑定两个周期,执行两次

6、插件识别方式

前置匹配:

  • 匹配规则:${prefix}-maven-plugin
  • artifactId:hello-maven-plugin
  • 前缀hello,插件名为hello

中间匹配:

  • 匹配规则:maven-${prefix}-plugin
  • artifactId:maven-good-plugin
  • 前缀:good
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-05-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1、Maven核心概念
    • 1.1、坐标
    • 1.2、POM
    • 1.3、约定的目录结构
  • 2、依赖管理
    • 2.1、依赖范围
    • 2.2、解决pom单继承问题
    • 2.3、可选依赖
    • 2.4、依赖的传递性
    • 2.5、版本优先级
    • 2.6、依赖的排除
    • 2.7、版本号
  • 3、继承
  • 4、聚合
  • 5、其他核心概念
    • 5.1、生命周期
    • 5.2、插件和目标
    • 5.3、生成微服务可运行 jar 包
    • 5.4、<resources>标签
  • 6、Maven 自定义插件
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档