maven-resources-plugin详解

本篇文章重点针对这几个问题进行讲解:

  • maven-resources-plugin到低在什么场景下使用?
  • 他到底有什么作用?
  • 他和pom当中配置的resources标签又有什么关联?
  • 为什么有的项目使用了该插件而有的却没有?
  • resources当中的filtering标签到低是干什么的?
  • maven怎么打包过滤文件?

一、什么场景会用到?

这个插件只要我们编译代码就会用到该插件,就算我们项目没有声明该插件也照样会使用到,怎么证明呢?

我们可以在一个新的maven项目,不添加任何依赖,然后使用mvn clean install

Maven 默认为一些核心的生命周期阶段绑定了插件目标,当用户调用这些阶段时,对应的插件目标就会自动执行相应的任务。其中maven-resources-plugin的resources和testResources两个目标,绑定到了default生命周期的process-resources和process-test-resources两个阶段上。

关于生命周期不是很理解的可以看一下这篇文章,本篇不过多介绍:https://blog.youkuaiyun.com/weixin_43888891/article/details/130756192

二、他有什么作用?

作用:他的作用是将项目的资源(resources目录下)目录的文件复制到输出目录(target),输出目录又分为了两个,一个是测试的输出目录,一个是主资源的。所以对应了process-resources和process-test-resources两个阶段上,当然一般测试目录并没有资源目录。

什么是资源文件?

.java文件在运行的时候需要通过JRE编译成.class文件,然后放到target目录,然后本地启动项目的时候,jvm运行target目录下的编译过后的.class代码文件,

而资源文件就是不属于.java文件,那也就意味着不需要参与编译工作,但是运行的时候又依赖与他。这时候就需要通过maven-resources-plugin插件将其放到编译后的路径。这样我们项目启动的时候资源文件才能被使用。这也就是我们有时候项目经常会出现明明代码当中有这个文件,但是运行却说找不到文件的原因。

假如对生命周期了解的,看下图应该很容易就明白插件的作用了:

官网介绍:https://maven.apache.org/plugins/maven-resources-plugin/

三、插件常用配置

1、字符集编码

在这里插入图片描述

既然插件是copy资源文件那必然涉及到文件的编码,可以选择的编码有ASCII, UTF-8 或者 UTF-16,设置编码的方式有两种

第一种:使用properties标签声明project.build.sourceEncoding,声明好后,插件当中的<encoding>标签会取这个编码

<project ...>
 ...
 <properties>
   <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
   ...
 </properties>
 ..
</project>

第二种通过插件配置:

<project>
  ...
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-resources-plugin</artifactId>
        <version>3.3.1</version>
        <configuration>
          ...
          <encoding>UTF-8</encoding>
          ...
        </configuration>
      </plugin>
    </plugins>
    ...
  </build>
  ...
</project>

注意:只要官网当中提到了可以使用${…}的方式配置,那么我们就可以不声明插件,可以直接在properties当中配置。

2、resources相关的配置

2.1、resources配置结构

resources标签其实就是maven-resources-plugin的配置,主要用来配置资源目录的

<build>
	<resources>
	  <resource>
	 		<directory>${project.basedir}/src/main/resources</directory>
	 		<filtering></filtering>
		  <includes>
	  			<include></include>
	 		</includes>
	  	<excludes>
	   			<exclude></exclude>
	  	</excludes>
	 </resource>
	  <!--假如资源目录有多个可以在这里声明-->
	  <resource>
	    ...
	  </resource>
	  
	</resources>
</build>
  • 标签<directory>指定资源文件目录
  • 标签 <includes>指定资源文件目录中,仅包含哪些文件被打包
  • 标签<excludes>指定资源文件目录中,仅哪些文件不被打包
  • 标签<filtering>是一个bool值,默认值为false。指定打包时的配置文件中是否进行变量替换
2.2、resources默认配置

所谓默认配置就是在项目当中不设置resources标签,他默认生效的

2.2.1、maven超级pom默认配置

maven项目默认继承了一个父pom.xml,配置主要包含了如下,其中一些配置就是对maven-resources-plugin插件的配置:

关于如何查看默认继承的pom配置,感兴趣的可以看这一篇文章:https://blog.youkuaiyun.com/weixin_43888891/article/details/130483451

  <build>
    <directory>${project.basedir}/target</directory>
    <!-- 主资源默认输出的位置 -->
    <outputDirectory>${project.build.directory}/classes</outputDirectory>
    <!--打出来的默认jar、war包名-->
    <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>
  </build>

比如outputDirectory就是maven-resources-plugin插件当中的配置如下:

2.2.2、spring-boot对resources插件的默认配置

springboot项目一般我们都会继承一个spring-boot-starter-parent,而他的pom当中就默认给我们做了一些resources插件的配置:

像这些resources标签的都是resources插件的配置,关于这个配置起到了什么作用后面会讲!

除此之外pluginManagement当中还存在resources插件的配置,如下:

2.2.3、resources最终生效的配置

假如我们项目没有继承spring-boot-starter-parent那么我们的项目默认继承了一个父pom,resources默认配置如下:

<resources>
  <resource>
    <directory>${project.basedir}/src/main/resources</directory>
  </resource>
</resources>

假如继承了spring-boot-starter-parent,那么我们的的项目resources默认配置如下,他会将maven默认配置给替换掉:

<resources>
  <resource>
    <directory>${basedir}/src/main/resources</directory>
    <filtering>true</filtering>
    <includes>
      <include>**/application*.yml</include>
      <include>**/application*.yaml</include>
      <include>**/application*.properties</include>
    </includes>
  </resource>
  <resource>
    <directory>${basedir}/src/main/resources</directory>
    <excludes>
      <exclude>**/application*.yml</exclude>
      <exclude>**/application*.yaml</exclude>
      <exclude>**/application*.properties</exclude>
    </excludes>
  </resource>
</resources>

这里需要注意一点:假如我们项目当中去声明resources标签,那么他会将继承的父类当中的resources标签给替换掉,说白了就是重写的会覆盖继承的

2.3、resources下的标签详解
2.3.1、filtering的使用

关于这个标签官网也有叙述:https://maven.apache.org/plugins/maven-resources-plugin/examples/filter.html

filtering默认为false,作用是是否允许指定任意文件可以以${...} or @...@的语法来提取pom.xml当中的配置。

用法示例:

1.资源文件中使用${keyword}占位符来定义变量, 如src/main/resouces/application.properties:

2.这时候可以在pom.xml文件中定义变量的取值

3.如果需要对配置文件中变量进行替换实际值,就需要开启<filtering>,该值设置为true。这里使用了includes标签指定了文件,也就是允许application.properties文件读取变量值。

<build>
	<resources>
		<resource>
			<directory>src/main/resources</directory>
			<filtering>true</filtering>
               <includes>
                   <include>application.properties</include>
               </includes>
           </resource>
	</resources>
</build>

4.执行mvn clean package -DskipTests 打包,然后打开target/classes目录当中查看资源文件,会发现使用 @...@取值成功了,而${...} 没有成功。

这个替换值是maven-resources-plugin插件的功能,其实我们不需要打包也可以测试,直接通过调用改插件的目标即可:mvn resources:resources

原因:这是因为我这个项目继承了spring-boot-starter-parent,而springboot的xml当中有一个这个标签<resource.delimiter>将取值语法改为了 @...@,因为spring害怕和其他语法有冲突,所以使用了这个配置。

我们也可以通过手动声明来覆盖springboot父类的配置,这样便可以通过${...}语法进行取值了。

<properties>
	<resource.delimiter>${*}</resource.delimiter>
</properties>

5.通过命令进行指定变量的值:mvn clean package -DskipTests -Dusername="lisi"

注:命令的优先级要高于pom当中配置的变量值

6.另, 变量的定义可以不放在pom里, 也可以指定其他文件, 通过build.filters.filter配置即可. 示例:

<build>
	<filters>
		<filter>src\main\resources\filters_file.properties</filter>
	</filters>
	<resources>
		<resource>
			<directory>src/main/resources</directory>
			<filtering>true</filtering>
            <includes>
                <include>application.properties</include>
            </includes>
        </resource>
	</resources>
</build>
2.3.2、为什么非得使用includes指定文件?

没有必要使用变量取值的,千万不要将filtering设置为true,针对于这一点官网也明确指出二进制文件一定不要过滤,之前我遇到过一个bug就是resources文件夹当中存放有Excel模板,导出模板后发现是乱码的,但是通过源代码打开Excel就是正常的,原因就是将文件给进行过滤了。导致编译过后target当中的Excel都是乱码的。

在这里插入图片描述

2.3.3、include和excludes的使用

关于这个标签官网也有叙述:https://maven.apache.org/plugins/maven-resources-plugin/examples/include-exclude.html

我们来看springboot默认的配置,针对于上面一个环节我们已经搞清楚了,但是下面的呢,为什么允许了,后面又使用exclude给过滤掉了呢?

其实实际开发当中很多人对这都是不理解,配置起来也是一顿乱配置。多读两遍我图片上写的注释,一旦理解了,就彻底懂了!

include和excludes标签也可以同时出现在一个resource当中,例如如下:
将以txt结尾的文件copy到target,需要排除掉文件名当中携带test的。

**/代表的是根目录,/src/main/resources 和 /src/main/java 这两个都属于根目录,一个*可以代表一个占位符,可以是多个字母组成的

<build>
  ...
  <resources>
    <resource>
      <directory>src/my-resources</directory>
      <includes>
        <include>**/*.txt</include>
      </includes>
      <excludes>
        <exclude>**/*test*.*</exclude>
      </excludes>
    </resource>
    ...
  </resources>
  ...
</build>
2.4、什么场景需要配置resources?
  1. 假如src/main/java下存在非.java文件,但是也需要参与打包,这时候需要手动配置resources,因为不管是maven默认继承的父pom还是springboot的父pom,都只会将resources下的资源文件参与打包。
  2. 如果项目继承了spring-boot-starter-parent,然后需要使用application.properties变量取值,是可以不配置的,因为springboot默认配置了,假如我们还有很多配置文件,例如application-dev.properties、application-prod.properties这些都需要使用变量取值,这时候就需要覆盖掉springboot的resources配置来手动配置。
  3. 有的项目会习惯性将每个版本的升级sql存放到resources文件夹下,假如我们不做任何配置的情况下,他也会参与打包。假如sql文件比较大,那打出来的jar包也一定很大。
  4. 默认的资源目录就是src/main/resources,假如项目有资源目录以外的文件需要参与打包这时候就需要手动指定。

关于resources标签当时我还专门写了一篇关于这个的文章,当时其实是似懂非懂,只能说通过亲自试验得出来了一些结论:https://blog.youkuaiyun.com/weixin_43888891/article/details/122406081

两篇文章结合着看基本上就可以彻底掌握了!

3、maven-resources-plugin配置

官网相关配置详解:https://maven.apache.org/plugins/maven-resources-plugin/resources-mojo.html

maven-resources-plugin插件是maven内置插件,我们就算项目不声明,调用的时候也会访问。一般项目当中本身也就不需要声明,基本上都是通过resources标签来控制资源文件的。

springboot父pom默认配置如下:

  • delimiter:就是更改变量取值的形式,上面也有提到过。
  • propertiesEncoding:就是字符编码

这是我当时在公司遇到的一个关于该插件的bug:https://blog.youkuaiyun.com/weixin_43888891/article/details/130089503

在彻底掌握了resources之后才发现原来公司很多开发都是一顿乱配置,包括我在内,哈哈哈

当时就是使用了filtering为true然后导致Excel压缩过后打不开了,然后添加了如下配置

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

这里有一点需要注意,springboot在父pom的pluginManagement设置了maven-resources-plugin,而我们又在项目当中声明了maven-resources-plugin,最终他生效的是父pom+我们声明的配置:

通过mvn help:effective-pom命令即可查看生效的pom

<think> 我们正在讨论maven-resources-plugin插件。根据引用内容,该插件主要用于处理资源文件。 引用[1]指出:该插件用于处理非源代码的资源文件,如配置文件。默认资源目录是src/main/resources和src/test/resources。 引用[2]提到:配置该插件后,默认的资源复制行为会被覆盖,需要显式配置资源复制。同时,可以设置编码(如UTF-8)。 引用[3]展示了一个配置示例:可以指定资源目录、包含的文件模式、是否进行过滤(filtering)等。 引用[4]说明了该插件的一个目标(goal)resources:resources,它负责将主资源复制到输出目录,并默认绑定到process-resources阶段。 因此,我们可以总结如下: # Maven Resources Plugin 详解 ## 1. 核心作用 - **资源文件处理**:将项目资源文件(如配置文件、属性文件等)复制到输出目录(通常是`target/classes`) - **资源过滤**:支持使用Maven属性(例如`${project.version}`)动态替换资源文件中的占位符 - **多环境支持**:通过不同profile配置实现资源文件的差异化处理 ## 2. 默认行为 - **默认资源目录**: - 主资源:`src/main/resources` - 测试资源:`src/test/resources` - **默认执行阶段**: - `process-resources`(主资源) - `process-test-resources`(测试资源) ## 3. 关键配置参数 | 参数名 | 说明 | 示例值 | |--------------|----------------------------------------------------------------------|--------------------------------| | `<directory>` | 资源文件所在目录 | `src/main/resources` | | `<includes>` | 指定包含的文件模式(支持Ant风格通配符) | `<include>**/*.properties</include>` | | `<excludes>` | 排除的文件模式 | `<exclude>**/test.*</exclude>` | | `<filtering>` | 是否启用属性替换(true/false) | `true` | | `<encoding>` | 资源文件编码(强烈建议显式设置) | `UTF-8` | ## 4. 完整配置示例 ```xml <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-resources-plugin</artifactId> <version>3.3.0</version> <!-- 推荐最新版本 --> <configuration> <!-- 全局编码设置 --> <encoding>UTF-8</encoding> <!-- 主资源配置 --> <resources> <resource> <directory>src/main/resources</directory> <includes> <include>**/*.xml</include> <include>**/*.properties</include> </includes> <filtering>true</filtering> <!-- 启用占位符替换 --> </resource> <!-- 添加额外资源目录示例 --> <resource> <directory>src/main/config</directory> <excludes> <exclude>**/secret.*</exclude> </excludes> </resource> </resources> </configuration> </plugin> </plugins> </build> ``` ## 5. 资源过滤机制 1. **启用条件**:`<filtering>true</filtering>` 2. **替换规则**: ```properties # 资源文件示例 (application.properties) app.version=${project.version} ``` 编译后: ```properties app.version=1.0.0 ``` 3. **自定义属性**:在`<properties>`中定义的属性可直接使用 ## 6. 常见问题解决 1. **乱码问题**: ```xml <!-- 必须显式设置编码 --> <encoding>UTF-8</encoding> ``` 2. **资源覆盖问题**: - 当配置多个`<resource>`时,**后定义的目录优先级更高** - 相同文件名资源会发生覆盖 3. **过滤失效排查**: - 检查`<filtering>`是否设置为true - 确认属性名拼写正确(区分大小写) §§相关问题§§ 1. 如何通过Maven Profile实现不同环境的资源配置? 2. 资源过滤时如何处理特殊字符(如@符号)? 3. 如何排除资源目录中的特定文件? 4. maven-resources-pluginmaven-source-plugin有何区别? 5. 如何扩展自定义资源目录? [^1]: Maven插件之maven-resources-plugin [^2]: maven-resources-plugin的使用 [^3]: maven中的maven-resources-plugin插件详解 [^4]: maven-resources-plugin </think>### Maven Resources Plugin 详解 #### 1. **核心作用** - **资源文件处理**:负责将非源代码资源文件(配置文件、属性文件等)复制到输出目录 - **资源过滤**:支持使用 Maven 属性(如 `${project.version}`)动态替换资源文件中的占位符 - **多环境支持**:通过不同配置实现开发/生产环境的资源差异化 #### 2. **默认行为** - **默认资源目录**: ```markdown src/main/resources → target/classes src/test/resources → target/test-classes ``` - **自动执行阶段**: - `process-resources`(主资源) - `process-test-resources`(测试资源) #### 3. **关键配置参数** | 参数 | 说明 | 示例值 | |---------------|----------------------------------------------------------------------|--------------------------------| | `<directory>` | 资源文件源目录 | `src/main/resources` | | `<includes>` | 包含的文件模式(Ant风格通配符) | `<include>**/*.properties</include>` | | `<excludes>` | 排除的文件模式 | `<exclude>**/test.*</exclude>` | | `<filtering>` | 是否启用属性替换(true/false) | `true` | | `<encoding>` | 资源文件编码(**必设项**,防乱码) | `UTF-8` | #### 4. **完整配置示例** ```xml <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-resources-plugin</artifactId> <version>3.3.0</version> <!-- 推荐最新稳定版 --> <configuration> <!-- 全局编码设置 --> <encoding>UTF-8</encoding> <!-- 主资源配置 --> <resources> <resource> <directory>src/main/resources</directory> <includes> <include>**/*.yml</include> <include>**/*.xml</include> </includes> <filtering>true</filtering> <!-- 启用占位符替换 --> </resource> <!-- 额外资源目录 --> <resource> <directory>src/main/config</directory> <excludes> <exclude>**/secret.*</exclude> <!-- 排除敏感文件 --> </excludes> </resource> </resources> </configuration> </plugin> ``` #### 5. **资源过滤机制** 1. **启用条件**:`<filtering>true</filtering>` 2. **替换规则**: ```properties # 资源文件示例 (app.properties) app.version=${project.version} ``` 编译后: ```properties app.version=1.0.0 # 被实际值替换 ``` 3. **特殊字符转义**:使用 `\` 避免 `@` 等符号被误解析 ```properties email=user\@example.com ``` #### 6. **与编译器插件的关系** - **执行顺序**: ```mermaid graph LR A[resources:resources] --> B[compiler:compile] C[resources:testResources] --> D[compiler:testCompile] ``` - **协作要点**: 1. 资源文件**先于**代码编译执行 2. 编译后的class文件可直接读取`target/classes`中的资源 #### 7. **常见问题解决** - **乱码问题**: ```xml <!-- 必须显式设置编码 --> <encoding>UTF-8</encoding> ``` - **资源未被复制**: 1. 检查`<includes>`模式是否匹配文件 2. 确认未配置`<excludes>`意外过滤 - **属性未替换**: 1. 验证`<filtering>`是否为true 2. 检查属性名拼写(区分大小写)
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

怪 咖@

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值