資源文件,最常見的 XML 、Properties 配置文件,比如使用 Mybatis 時的 Mapper,Spring 的 ApplicationContext 配置。
打包(package)
根據 Maven 的默認項目結構,資源文件放置在 src/main/resources 中,測試的資源文件在 src/test/resources 中。放置在 src/main/resources 中的資源文件默認會被打包進 jar 中。
例如我們有如下的目錄結構,其中在 src/main/resources
中有一個資源文件 application.properties 在 META-INF
中
my-app
|-- pom.xml
`-- src
|-- main
| |-- java
| | `-- com
| | `-- mycompany
| | `-- app
| | `-- App.java
| `-- resources
| `-- META-INF
| `-- application.properties
`-- test
`-- java
`-- com
`-- mycompany
`-- app
`-- AppTest.java
我們將上面的項目進行打包,然後將 jar 解壓之後我們可以看到如下的目錄
|-- META-INF
| |-- MANIFEST.MF
| |-- application.properties
| `-- maven
| `-- com.mycompany.app
| `-- my-app
| |-- pom.properties
| `-- pom.xml
`-- com
`-- mycompany
`-- app
`-- App.class
如上所示,我們可以發現項目中的 src/main/resources
目錄中的文件會被打包在項目根目錄中。這裏多出來的 pom.properties
跟 pom.xml
是 Maven 在打包的時候默認生成的,當然你可以創建你自己的打包清單。
但有時候,我們的資源文件沒有全部放置的 src/main/resources
中,比如 Mybatis 的映射文件有時候會直接放置在相關的類包中,這時候打包就不會將這些映射文件打包進 jar 中,引用該 jar 的其他項目在使用相關的類就會報錯。這時候我們就需要指定需要打包的資源文件。有以下幾種方法
(1) <resources>
標籤
<resources>
標籤位於 <build>
標籤內,用於指定項目資源文件的位置。例如,我們有一個 configuration.xml
文件,我們的項目要求這個文件位於 META-INF/plexus
中,雖然我們可以將其放置在 src/main/resource/META-INF/plexus
中,但我們給了這個文件自己的目錄 src/main/plexus
,爲了將其正確地打包進 jar 中,我們可以使用如下的配置
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
https://maven.apache.org/xsd/maven-4.0.0.xsd">
<build>
...
<resources>
<resource>
<targetPath>META-INF/plexus</targetPath>
<filtering>false</filtering>
<directory>${basedir}/src/main/plexus</directory>
<includes>
<include>configuration.xml</include>
</includes>
<excludes>
<exclude>**/*.properties</exclude>
</excludes>
</resource>
</resources>
<testResources>
...
</testResources>
...
</build>
</project>
- resources:資源文件列表
- targetPath:放置資源文件的目錄,默認是根路徑
- filtering:是否過濾資源文件
- directory:資源文件所在目錄
- includes:需要包含的文件列表
- excludes:需要排除的文件列表
- testResources:測試資源文件列表,配置類似 resources
(2) 配置 Resources 插件
Apache Maven Resources Plugin
有 3 個 goals,分別是
- resources:resources
- resources:testResources
- resources:copy-resources
當我們配置 <resources>
標籤的時候,resources:resources
目標就會使用到 <resources>
中的配置,如果不配置 <resources>
,我們可以使用 resources:copy-resources
目標,這裏我將其綁定在 process-resources
階段中
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.7</version>
<executions>
<execution>
<id>my-resources</id>
<phase>process-resources</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${project.build.outputDirectory}</outputDirectory>
<resources>
<resource>
<targetPath>META-INF/plexus</targetPath>
<filtering>false</filtering>
<directory>${basedir}/src/main/plexus</directory>
<includes>
<include>configuration.xml</include>
</includes>
<excludes>
<exclude>**/*.properties</exclude>
</excludes>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
過濾(filter)
有時候我們需要在構建的時候給資源文件提供一些值,要在 Maven 完成這種工作,我們需要在資源文件中使用 ${<property name>}
這樣的語法。這個屬性值,可以定義在 pom.xml 中,也可以定義在用戶的 settings.xml 中(關於 settings.xml ,參考這裏 ),或者是另外的 properties 文件中,或者是一個系統屬性。
要進行過濾,首先在 pom.xml 中爲資源文件目錄設置 filtering
爲 true
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Maven Quick Start Archetype</name>
<url>http://maven.apache.org</url>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
</project>
默認情況下 filtering
爲 false
,所以首先需要重寫默認設置。
(1)引用 pom.xml 中定義的屬性
通常在 pom.xml 中已經有一些有默認值屬性,所以我們不需要一一聲明這些屬性。類似於 ${project.build.finalName}
,${project.version}
等,這些屬性名使用 xml 中的標籤名,所以 project 表示 <project>
標籤,project.name 就表示 project 標籤中的 name 標籤。
我們也可以在 pom.xml 中的定義 <properties>
標籤來定義屬性,如
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Maven Quick Start Archetype</name>
<url>http://maven.apache.org</url>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
<properties>
<my.filter.value>hello</my.filter.value>
</properties>
</project>
那麼當我們有一個資源文件 src/main/resources/application.properties
# application.properties
application.name=${project.name}
application.version=${project.version}
message=${my.filter.value}
當我們執行命令 mvn process-resources
時,在生成的 application.properties 文件中我們可以看到如下
# application.properties
application.name=Maven Quick Start Archetype
application.version=1.0-SNAPSHOT
my.filter.value=hello!
(2)使用額外的屬性文件
例如我們有一個屬性文件 src/main/filters/filter.properties
# filter.properties
my.filter.value=hello!
然後,我們需要在 pom.xml 中爲這個文件增加一個引用
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Maven Quick Start Archetype</name>
<url>http://maven.apache.org</url>
<build>
<filters>
<filter>src/main/filters/filter.properties</filter>
</filters>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
</project>
最後在需要過濾的資源文件中增加屬性引用
# application.properties
application.name=${project.name}
application.version=${project.version}
message=${my.filter.value}