Mavenfiltering详解

发布时间:2023-05-23

一、Maven filtering概述

Maven filtering是Maven的一个重要插件,主要用于过滤文件(过滤资源文件、过滤属性文件等)。Maven filtering已被广泛应用于各种项目中,使开发更加高效、优雅。下面我们来进一步了解Maven filtering的使用。

二、Maven filtering使用方法

1. 基本使用方法

Maven filtering的基本使用方法是在一个项目的pom.xml文件中添加以下配置:

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-resources-plugin</artifactId>
            <version>3.0.2</version>
            <executions>
                <execution>
                    <id>copy-resources</id>
                    <phase>validate</phase>
                    <goals>
                        <goal>copy-resources</goal>
                    </goals>
                    <configuration>
                        <outputDirectory>${project.build.directory}</outputDirectory>
                        <resources>
                            <resource>
                                <directory>src/main/resources</directory>
                                <filtering>true</filtering>
                            </resource>
                        </resources>
                        <filtering>
                            <filters>
                                <filter>src/main/filters/filter.properties</filter>
                            </filters>
                        </filtering>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

其中,主要配置信息如下:

  • resources:指定要过滤的资源文件路径
  • directory:指定要过滤的资源文件所在目录
  • filtering:设为true,表示开启过滤机制
  • filters:指定要用到的过滤器文件

2. 过滤器

Maven filtering提供了几种过滤器,常用的有以下三种:

  • properties:将${xxx}形式的属性变量替换为定义的属性值
  • tokens:将@变量@替换为定义的变量值 或 context(maven .properties, pom values, environment variables, execution properties, resource file entries)中的值
  • XML:将${xxx}形式的属性值替换,并能支持XML编码及其它一些编码格式 过滤器配置方法如下:
<filter>
    <skipExistingFilters>true</skipExistingFilters>
    <files>
        <file>src/main/filters/filter.properties</file>
    </files>
</filter>

3. 过滤资源文件

过滤资源文件是Maven filtering的一大特色。 Maven filtering支持多种类型的资源文件,包括HTML、CSS、JavaScript、XML、Java源代码以及属性文件等。例如,可以指定一些属性文件,并在编译时将其中的属性替换为相应的值。

<resources>
    <resource>
        <directory>${basedir}/src/resources/</directory>
        <filtering>true</filtering>
        <includes>
            <include>*.properties</include>
        </includes>
    </resource>
</resources>

4. 使用Maven filtering处理jar包

Maven filtering还可以被用于处理jar包中的文件。将Maven project打包成jar(包含主类等等信息),并创建一个jar-only的artifact供项目依赖使用,可使用maven-jar-pluginmaven-dependency-plugin。 配置方法如下:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <version>2.4</version>
    <executions>
        <execution>
            <id>prepare-jar-exploded</id>
            <phase>package</phase>
            <goals>
                <goal>jar</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <archive>
            <manifest>
                <addClasspath>true</addClasspath>
                <classpathPrefix>lib/</classpathPrefix>
                <mainClass>com.a.b.Main</mainClass>
            </manifest>
            <manifestEntries>
                <Properties-Overwrite>true</Properties-Overwrite>
            </manifestEntries>
        </archive>
    </configuration>
</plugin>

5. 通过maven-assembly插件打包文件

maven-assembly插件可以将多个jar文件打包成一个jar文件,并且可以指定多个依赖包或者资源文件。 使用maven-assembly插件配置Maven filtering的方法如下:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-assembly-plugin</artifactId>
    <version>3.3.0</version>
    <executions>
        <execution>
            <id>make-assembly</id>
            <phase>package</phase>
            <goals>
                <goal>single</goal>
            </goals>
            <configuration>
                <finalName>simpleApp</finalName>
                <appendAssemblyId>false</appendAssemblyId>
                <descriptors>
                    <descriptor>src/main/resources/assembly.xml</descriptor>
                </descriptors>
            </configuration>
        </execution>
    </executions>
</plugin>

三、Maven filtering应用场景

1. 多环境部署

在开发中,经常会遇到多环境问题。不同的环境分别对应不同的配置文件,例如数据库连接、缓存服务器等,这时就需要用到Maven filtering。

2. 引用资源

对于一些外部引用的资源文件,如Spring配置文件、Hibernate配置文件等,可以在这些文件中使用${xxx}的形式进行变量引用,然后通过Maven filtering进行替换。

3. 动态生成软件版本号

可以通过Maven filtering来动态生成软件版本号。例如在pom.xml中添加以下配置:

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-filtering</artifactId>
            <version>3.0.2</version>
            <executions>
                <execution>
                    <id>filter-version</id>
                    <phase>generate-resources</phase>
                    <goals>
                        <goal>filter</goal>
                    </goals>
                    <configuration>
                        <filters>
                            <filter>${basedir}/src/main/filters/versions.properties</filter>
                        </filters>
                        <delimiters>
                            <delimiter>@</delimiter>
                        </delimiters>
                        <outputDirectory>${project.build.directory}/${project.artifact}</outputDirectory>
                        <overwrite>true</overwrite>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

关于versions.properties的内容如下:

version=@pom.version@

4. 灵活替换pom.xml内容

在运行时,可以通过-MPACKAGE参数来替换pom.xml文件中的属性值。

mvn -DappName=test -Dversion=1.0 -DMPACKAGE="-Dappname=test -Dversion=1.0" package

四、Maven filtering注意事项

1. 避免属性名与文件名和文件路径产生冲突

当需要在filter.xml文件中定义的环境变量与文件名和文件路径产生冲突时,标签中的prefix属性可用于解决该问题。

<filter>
    <prefix>env3_</prefix>
    <files>
        <file>src/main/filters/filter.properties</file>
    </files>
</filter>

2. 复制属性到MANIFEST文件中

为确保MANIFEST.MF文件中使用的属性正确,内部Maven过程将另存储所有与环境相关的属性,并在存档时覆盖MANIFEST.MF,而无需再次查询环境。此过程将忽略任何以pom.*project.*为前缀的属性文件,因为它们已在该pom.xml文件中。任何写入系统属性的插件也需要自己处理这种情况。

3. 不要过度使用过滤器

为了避免过度使用过滤器造成的疑难问题,建议您仅对确实需要过滤的文件使用它。