filtering标签和includes,excludes标签都是resource标签下的标签,它们经常出入成双。然而这两者根本就是截然不同的。

      filtering用于扩大范围,什么范围呢?maven默认只会替换pom文件中的占位符属性,不会触碰resources下相关文件的.但filtering=true了,就可以触碰了,触碰的效果就是能替换resources下指定文件的占位符属性.

      默认情况下,maven打包时会包含resources下所有的文件.如果我们只想让指定的几个文件被打包,那就将这几个文件放在includes标签下处理;同理: 如果我们不想让这几个文件被打包,那就将这几个文件放在excludes标签下处理.

filtering的单独使用
  1. 没有使用filtering时:

      pom文件中定义在不同激活区的属性xxx

<profiles>
    <profile>
        <id>dev</id>
        <properties>
            <xxx>dev</xxx>
        </properties>
    </profile>
    <profile>
        <id>sit</id>
        <properties>
            <xxx>sit</xxx>
        </properties>
    </profile>
    <profile>
        <id>uat</id>
        <properties>
            <xxx>uat</xxx>
        </properties>
    </profile>
</profiles>

bootstrap.properties文件中定义的占位符属性${xxx}

spring.cloud.config.profile=${xxx}

使用-Psit打包后target下对应文件原封不动,没被替换:

spring.cloud.config.profile=${xxx}
  1. 使用filtering后:
<build>
    <resources>
        <resource>
            <directory>${project.basedir}/src/main/resources</directory>
            <filtering>true</filtering>
        </resource>
    </resources>
</build>

使用-Psit打包后target下对应文件中${}占位符被替换了:

spring.cloud.config.profile=sit

3.注意点:

  • 若单纯是maven项目,则可以使用${}占位符;
  • 若是springboot项目,则占位符需使用@xxx@,使用${}将失效.spring-boot-starter-parent为了防止与pom的占位符冲突,通过maven-resources-plugin将maven使用的资源占位符专门设置为:@ ,如下:
<properties>
   <java.version>1.6</java.version>
   <resource.delimiter>@</resource.delimiter> <!-- delimiter that doesn't clash with Spring ${} placeholders -->
   <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
   <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
   <maven.compiler.source>${java.version}</maven.compiler.source>
   <maven.compiler.target>${java.version}</maven.compiler.target>
</properties>

<plugin>
   <groupId>org.apache.maven.plugins</groupId>
   <artifactId>maven-resources-plugin</artifactId>
   <version>2.6</version>
   <configuration>
      <delimiters>
         <delimiter>${resource.delimiter}</delimiter>
      </delimiters>
      <useDefaultDelimiters>false</useDefaultDelimiters>
   </configuration>
</plugin>

可通过自己配置plugin覆盖此处配置:

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-resources-plugin</artifactId>
            <version>3.1.0</version>
            <configuration>
                <encoding>utf-8</encoding>
                <!-- 使Spring Boot支持${}占位符 -->
                <useDefaultDelimiters>true</useDefaultDelimiters>
            </configuration>
        </plugin>
    </plugins>
</build>
includes与excludes的使用

resources下文件有多个:
在这里插入图片描述

  • 如果使用了include
<build>
    <resources>
        <resource>
            <directory>${project.basedir}/src/main/resources</directory>
            <includes>
                <include>dev/</include>
            </includes>
        </resource>
    </resources>
</build>

则打包时进入target的是这样的:

  • 如果使用了exclude
<build>
    <resources>
        <resource>
            <directory>${project.basedir}/src/main/resources</directory>
            <excludes>
                <exclude>dev/</exclude>
            </excludes>
        </resource>
    </resources>
</build>

则打包时进入target的是这样的:
在这里插入图片描述

  • 如果同时使用了include和exclude,
<build>
    <resources>
        <resource>
            <directory>${project.basedir}/src/main/resources</directory>
            <includes>
                <include>dev/</include>
            </includes>
            <excludes>
                <exclude>dev/application-dev.*</exclude>
            </excludes>
        </resource>
    </resources>
</build>

则打包时是这样的:
在这里插入图片描述
一个排除,一个包含,可以各自单独使用,也可以混合使用,混合使用时,如果范围有交集,会被排除掉,通常用于过滤掉文件夹中的几个特殊文件

filtering与include,exclude混合使用

有三大作用:

  1. 排除资源-------使用excludes排除

  2. 包括资源, 替换属性-------使用include包含, 且使用filtering=true过滤

  3. 包括资源, 不替换属性-------使用include包含,且不使用filtering过滤

如果这样用:

<build>
    <resources>
        <resource>
            <directory>${project.basedir}/src/main/resources</directory>
        //资源过滤: 只保留dev文件夹下名字不是application-dev的文件
            <includes>
                <include>dev/</include>
            </includes>
            <excludes>
                <exclude>dev/application-dev.*</exclude>
            </excludes>
        //扩大属性替换范围: 替换资源过滤最终留下来的文件中的@xxx@占位符属性
            <filtering>true</filtering>
        </resource>
    </resources>
</build>

那么打包结果:
在这里插入图片描述
target文件夹下的application-dev2.properties文件的属性值变化:

spring.cloud.config.profile=${xxx}    ----->      spring.cloud.config.profile=sit

总结:

  1. filtering用于打包时扩大maven替换占位符属性的范围, true表示会替换所在resource标签确定的文件范围内的占位符属性

  2. include和exclude用于打包时资源过滤, 主要目的是把resources下不想要的文件排除掉,不打进包中.

  3. 它俩都是resource标签下的子标签, 一个用于过滤资源,一个用于是否替换占位符属性, 一般都是搭配使用, 但两者功能迥异.

扩展:

在springboot项目中,spring-boot-starter-parent存在以下代码:

<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*.yml</exclude>
          <exclude>**/application*.properties</exclude>
        </excludes>
      </resource>
    </resources>

      其中第一段<resource>配置声明:在src/main/resources目录下,仅**/application*.yml、**/application*.yml、**/application*.properties文件是资源文件,参与打包过程;并且这些文件可以被替换占位符属性。
      第二段<resource>配置声明:同样在src/main/resources目录下,除**/application*.yml、**/application*.yml、**/application*.properties文件外的其他文件是资源文件,参与打包过程;并且这些文件不能被替换占位符属性。

注意:

  • 一个<resource>代表一个资源配置。不同的<resource>并无关系。前面提到的<include>和<exclude>在同一个<resource>中,即对同一个资源进行资源管理;而在spring-boot-starter-parent中,<include>和<exclude>在不同的<resource>,分别对各自<resource>进行管理。
  • 若在自己的pom中配置如下:
<resources>
            <resource>
                <directory>${basedir}/src/main/resources</directory>
                <filtering>true</filtering>
                <includes>
                    <include>**/application*.yml</include>
                </includes>
            </resource>
            <resource>
                <directory>${basedir}/src/main/resources</directory>
                <excludes>
                    <exclude>**/application*.yml</exclude>
                </excludes>
            </resource>
        </resources>

将会覆盖spring-boot-starter-parent中的代码,即spring-boot-starter-parent中的代码将失效。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐