Maven學習-處理資源文件

在前面兩篇文章中,咱們學習了Maven的基本使用方式和Maven項目的標準目錄結構。接下來,咱們來看下Maven是若是管理項目中的資源文件的。html

Java項目的資源文件,主要用於存儲系統的配置信息,以及提供系統集成的配置文件。項目中的資源文件夾下通常都存儲了以.properties爲後綴的文件以及.xml爲後綴的文件,用於記錄系統的上下文關係、log以及jdbc相關的配置信息。java

爲Jar包添加資源文件

在咱們使用POM管理項目的時候,咱們在進行打包的時候,須要將項目中的資源文件一塊兒打包到最終的jar包中。因此,咱們須要將那些資源文件放置在Maven能夠識別的目錄下。數據庫

在前一篇介紹Maven目錄結構的文章中,咱們提到了在Maven的項目目錄下,有一個默認的目錄用於存放項目的資源文件:${basedir}/src/main/resources。全部存放在這個目錄下的資源文件,當Maven進行打包的時候,就會將該目錄下的資源文件一塊兒打包到jar包中。Maven打包的時候,會按照該${basedir}/src/main/resources目錄下資源文件組織的目錄結構,在jar包的根目錄下也會有相同的目錄層次結構。apache

好比:bash

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包之後,jar包中的目錄結構以下所示:app

|-- META-INF
|   |-- MANIFEST.MF
|   |-- application.properties
|   `-- maven
|       `-- com.mycompany.app
|           `-- my-app
|               |-- pom.properties
|               `-- pom.xml
`-- com
    `-- mycompany
        `-- app
            `-- App.class

咱們能夠看到,資源文件application.properties在咱們的項目中是在META-INFO目錄下,而打包之後,該文件仍舊是在該目錄下,而META-INFO目錄是存放在jar包的根目錄下的。maven

上面咱們只是介紹了咱們項目中系統須要的資源文件的存放位置,對於項目中的單元測試,也能夠由一套本身的資源文件。這些資源文件存放的目錄結構和上面的相似,只不過存放的目錄名不一樣。單元測試相關的資源文件存放在${basedir}/src/test/resources目錄下,和前面的目錄對比,咱們能夠發現,區別只是src目錄下的main目錄和test目錄而已。這也是爲何測試相關的代碼和資源都是在test目錄下,而系統相關的代碼和資源都存放在main目錄下,這樣能夠方便識別。ide

咱們能夠看下一個包含單元測試資源文件的目錄結構:單元測試

my-app
|-- pom.xml
`-- src
    |-- main
    |   |-- java
    |   |   `-- com
    |   |       `-- mycompany
    |   |           `-- app
    |   |               `-- App.java
    |   `-- resources
    |       `-- META-INF
    |           |-- application.properties
    `-- test
        |-- java
        |   `-- com
        |       `-- mycompany
        |           `-- app
        |               `-- AppTest.java
        `-- resources
            `-- test.properties

若是咱們須要在Java代碼中訪問項目的資源文件,好比上面的test.properties文件,咱們只須要書寫相似下面的代碼:學習

InputStream is = getClass().getResourceAsStream( "/test.properties" );

咱們在寫代碼讀取資源文件時,定位資源文件的位置的時候,須要參考實際該資源文件最終在jar包中存放的位置,而不是項目中的位置。按照上面提到的,在jar包中,是按照項目的resources目錄下的目錄結構,在jar包的根目錄下產生相同的目錄結構的。對於上面的test.properties文件,在jar包中就是存放在jar包的根目錄下,因此咱們能夠在代碼中直接這麼定位該文件的位置"/test.properties"

如今,咱們已經知道了Maven是如何管理資源文件的了。接下來,咱們來看下Maven提供的一種處理資源文件的機制,能夠很方便的配置項目的資源。

過濾資源文件

有時候,咱們的資源文件中設置的值,只能在構建項目的時候纔會被指定。爲了完成這個需求,在Maven中能夠爲這個須要在構建的時候才能夠肯定值的位置,放置一個佔位符,來表示這個將來會被設置的值。經過使用${property}的方式指定。其中property能夠是指定在pom.xml文件中的值,或者是在setting.xml文件中設置的值,或者是放在項目的filters目錄(參考Maven的項目目錄結構)下的外部的properties文件中的值,亦或是一個系統屬性。這種方式在Maven中稱爲對資源文件的過濾。

爲了使得Maven在將資源文件打包時對一個資源文件進行過濾處理,能夠在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>

在上面的例子中,咱們在pom.xml文件中添加了一個<build>...</build>元素,在這個<build>元素中,咱們定義了<resources>元素來指定資源相關的配置,在<resources>元素下的<resource>元素中,咱們能夠指定哪一個資源文件須要Maven進行過濾處理。在這裏,咱們經過<directory>元素指定了須要被Maven進行過濾的資源文件目錄爲src/main/resources<filtering>元素指定這個資源目錄是否須要被Maven進行過濾處理,默認是false,表示不進行處理。

當咱們須要引用定義在pom.xml的文件中屬性的時候,引用的屬性的名字使用定義這個屬性的XML元素的名字。使用pom前綴表示項目根元素的別名。好比,${pom.name}引用定義在pom.xml文件中的項目的名字,${pom.version}引用項目的版本,${pom.build.finalName}引用項目的finalName(finalName是項目最終被打包之後的名字)。相似的,若是是引用定義在setting.xml文件中的名字,可使用${setting.localRepository}名字來引用,引用的時候須要加上setting前綴。

下面是一個使用Maven資源過濾的一個例子:

假設咱們有一個application.properties文件,放在目錄src/main/resources下,文件中的內容以下:

application.name=${pom.name}
application.version=${pom.version}

而後,咱們執行下面的命令來處理資源文件:

$ mvn process-resources

process-resources命令會複製項目中的資源文件到目錄target/classes中,並進行過濾處理。

運行完之後,咱們能夠看到application.properties文件已經被實際的屬性值替換了:

application.name=Maven Quick Start Archetype
application.version=1.0-SNAPSHOT

接下來,咱們來看下怎樣引用定義在外部的properties文件中的值。首先,咱們在Maven項目的的/src/main/filters目錄下添加一個properties文件filter.properties,咱們在文件中定義一個屬性鍵-值對:

my.filter.value=test

接下來,爲了讓Maven能夠知道這個文件的存在,咱們須要在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>

在上面的pom.xml文件中,有一條定義在<filters>元素中的語句<filter>src/main/filters/filter.properties</filter>,指定了這個外部properties文件來對資源文件進行過濾處理。若是存在多個能夠用於過濾的外部properties文件,能夠定義多個<filter>元素來指定。

下面,咱們在原來的application.properties文件中添加一條屬性來引用外部properties文件中的my.filter.value的值:

application.name=${pom.name}
application.version=${pom.version}
message=${my.filter.value}

而後當咱們執行mvn process-resources命令的時候,會使用外部properties文件中的值來替換application.properties文件中的message屬性的${my.filter.value}的值了。

除了咱們使用外部properties文件來實現上面的效果以外,咱們也可使用另一種方式來達到上面同樣的效果。只須要在pom.xml文件中定義<properties></properties>元素來定義咱們須要過濾的屬性,好比上面的my.filter.value屬性:

<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>test</my.filter.value>
  </properties>
</project>

上面的pom.xml文件中,咱們在<properties></properties>元素中定義了一個名爲<my.filter.value>的元素,這樣,咱們就能夠在資源文件中直接引用這個元素中定義的屬性值了。達到和上面使用外部properties文件同樣的效果。

下面,咱們看下如何得到系統級別的屬性吧。

被Maven過濾的資源文件,能夠得到系統級別的屬性,以及Java內建的屬性,好比java.versionjava.home。咱們也能夠得到命令行下傳遞過來的屬性值,經過-D選項來指定:

咱們修改以前的application.properties文件,添加如下的內容:

java.version=${java.version}
command.line.prop=${command.line.prop}

如今,咱們執行下面的命令:

$ mvn process-resources "-Dcommand.line.prop=hello world"

上面的命令,在命令行上經過-D選項指定了一個屬性值,因此咱們在過濾資源文件的時候會得到這個值,並進行替換。

執行之後,在target/classes目錄下的application.properties文件中,會變成這樣:

java.version=1.7.0_79
command.line.prop=hello world

好了,到這裏,咱們已經把Maven對資源文件過濾的內容介紹的差很少了。接下來,咱們來看一個使用Maven資源文件過濾的實際例子:

如今咱們有這樣一個問題,咱們在開發過程當中須要多套配置數據來配置開發環境,好比數據庫地址的配置等信息。咱們須要在多個開發情景下進行切換,若是咱們將配置信息寫死在資源文件中,那麼在咱們切換的時候,會比較繁瑣,還可能出現拼寫錯誤,特別是涉及到IP地址的修改的時候。因此,咱們能夠定義兩套配置方案,經過Maven的資源過濾機制,能夠很方便的進行切換。

首先,假設咱們有開發和測試兩個開發情景,那麼,咱們能夠定義兩個對應的properties文件:dev-filter.propertiestest-filter.properties。把這兩個文件放在項目的filters目錄下,做爲外部properties文件。

兩個文件的定義以下:

# dev-filter.properties
db.url=192.168.31.101

# test-filter.properties
db.url=192.168.32.102

如今,加上咱們的數據庫鏈接的配置是放在jdbc.properties這個資源文件中:

jdbc.url=${db.url}

那麼,咱們須要在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>
    <filters>
      <filter>src/main/filters/filter-${env}.properties</filter>
    </filters>
    <resources>
      <resource>
        <directory>src/main/resources</directory>
        <filtering>true</filtering>
      </resource>
    </resources>
  </build>
</project>

如今,咱們只是能夠對jdbc.properties這個資源文件進行過濾了,可是,咱們注意到,在上面的pom.xml文件中,在定義外部properties文件的時候,使用了一個名爲${env}的變量,因此,咱們接下來要定義這個env變量,來實現不一樣開發情景的切換。咱們使用了Maven的profile來實現:

<profiles>
   <!-- 開發環境,默認激活 -->
    <profile>
        <id>dev</id>
        <properties>
            <env>dev</env>
        </properties>
        <activation>
            <activeByDefault>true</activeByDefault>
        </activation>
    </profile>
    <!-- 測試環境 -->
    <profile>
        <id>test</id>
        <properties>
            <env>test</env>
        </properties>
    </profile>
</profiles>

上面的代碼中定義了變量env,將上面的代碼放到pom.xml文件中,就能夠實現開發環境和測試環境的切換了。

咱們能夠用下面的命令來進行切換:

$ mvn clean package -Pdev   # 將Maven切換到開發情景
$ mvn clean package -Ptest  # 將Maven切換到測試情景

好了,對Maven的資源的處理,就介紹到這裏。若是您以爲文章寫的還行,不妨動動您的鼠標,點個贊吧~

引用

https://maven.apache.org/guides/getting-started/index.html

相關文章
相關標籤/搜索