Spring Boot Maven Filter 问题

我们可以在项目的pom.xml文件中添加如下内容,其会把src/main/resources目录下的所有文件都当做咨询文件,此外通过true指定了这些资源文件将经过过滤。过滤的时候可以使用pom.xml中定义的properties或project相关信息等。

<build>
    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <filtering>true</filtering>
        </resource>
    </resources>
</build>

比如在src/main/resources目录下有个文件app.properties,其定义了app.version=${project.version},通过filter编译后app.properties文件中的${project.version}将会替换为pom.xml中project元素下的version元素的文本值。这是Maven的标准功能。但如果你的项目指定了spring-boot-starter-parent为父工程,则在资源文件中使用的${}占位符内容不会被filter替换。通过查看spring-boot-starter-parent的pom.xml文件可以看到其把分隔符指定为属性resource.delimiter的值。

<plugin>
    <artifactId>maven-resources-plugin</artifactId>
    <configuration>
        <delimiters>
            <delimiter>${resource.delimiter}</delimiter>
        </delimiters>
        <useDefaultDelimiters>false</useDefaultDelimiters>
    </configuration>
</plugin>

查看properties中定义的resource.delimiter可以看到分隔符被定义为@了。

<properties>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <java.version>1.8</java.version>
    <resource.delimiter>@</resource.delimiter>
    <maven.compiler.source>${java.version}</maven.compiler.source>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.target>${java.version}</maven.compiler.target>
</properties>

所以此时如果需要资源文件中的占位符能够正常被替换,需要改写为类似为app.version=@project.version@形式。或者在自己的pom.xml中的properties元素下定义自己的resource.delimiter,但是最好不要使用${},因为Spring自身的占位符也是${},如果有个资源文件中有个属性原本是期望Spring替换的,结果被Maven替换了就不好了。这也是Spring官方把它分开的原因。

通常使用Maven的filter时用来替换占位符的属性值不会直接定义在pom.xml中,而是定义在一个外部的properties文件中,此时可以通过filter元素进行引用。比如下面的配置指定了用来filter的属性值使用src/main/resources/config.properties文件(此时占位符中使用project的相关属性,比如project.version也还是可以的,包括使用properties元素下定义的内部属性、系统属性等也是OK的)。

<build>
    <filters>
        <filter>src/main/resources/config.properties</filter>
    </filters>
    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <filtering>true</filtering>
        </resource>
    </resources>
</build>  

Maven的filter一般会跟profile一起使用,基于不同的profile使用不同的属性配置文件来替换占位符,该工作也可以使用Spring的profile实现。