Maven Document翻译——Maven入门指南(中篇)

我如何使用插件?

无论何时你想去定制化你

在一个单元测试中你可以利用一小段代码如下去访问需要的资源文件:

...
// Retrieve resource
InputStream is = getClass().getResourceAsStream( "/test.properties" );
// Do something with the resource
...

我如何过滤资源文件?

有时候资源文件需要包含一个值,这个值只能在构建时期使用。为了完成这个功能,利用${<propertyname>}就可以将这个值带入你的资源文件。这个属性可以是你在pom.xml中定义的一个值,用户的setting.xml中的一个值,外部properties文件中的一个值,或者是一个系统属性。 为了在复制时利用Maven过滤资源,简单的设置filtering为真即可:

<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>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
  </dependencies>

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

你会注意到我们不得不增加build,resources,resource元素,此外我们不得不明确声明资源文件的位置是src/mai/resources目录。左右的这些信息都是默认提供的,但是因为默认的filteringfalse的,我们不得不增加这些信息到我们的pom.xml,为了去重写默认值并且将filtering设置为true。 为了引用你在pom.xml中定义的属性,属性名称利用xml元素名称去定义值,pom运行将项目元素作为一个别名,因此${project.version}指的是项目的名称,${project.version}指的是你项目的版本,${project.build.finalName}指的是在项目打包时生成的文件的最终的名称等等。注意一些POM元素拥有默认值,因此不需要明确的在pom.xml中定义。同样,用户的setting.xml中的值可以利用一settings开头的属性名来引用(比如,${settings.localRepository}指的是用户的本地路径)。 继续我们的例子,让我们在application.properties中增加两个属性(这个文件我们放到src/main/resources).当资源文件被过滤后,这个文件中的值将会被应用(过滤可以看作扫描):

# application.properties
application.name=${project.name}
application.version=${project.version}

到这里,你可以执行如下的命令(process-resources是构建生命周期阶段资源的复制和筛选):

mvn process-resources

application.properties文件在target/classes就像如下:

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

为了引用定义在外部文件中的属性,你所做的事需要增加一个外部文件的引用到你的pom.xml文件中。首先,让我们创建外部属性文件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>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
  </dependencies>

  <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.properties
application.name=${project.name}
application.version=${project.version}
message=${my.filter.value}

下一步执行mvn process-resources命令将会把我们的新属性值放进application.properties。除了定义my.filter.value在外部文件,你也可以定义其在pom文件中的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>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
  </dependencies>

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

  <properties>
    <my.filter.value>hello</my.filter.value>
  </properties>
</project>

过滤资源同样可以获取系统属性;java内建的系统属性(比如java.version或者user.home)或者利用java -D 参数定义在命令行的属性。继续我们的例子,让我们改变application.properties文件像如下:

# application.properties
java.version=${java.version}
command.line.prop=${command.line.prop}

现在,当我们执行如下的命令(注意定义在命令行的command.line.prop的属性),application.properties文件将会包含属性系统属性的值.

mvn process-resources "-Dcommand.line.prop=hello again"

我如何使用外部的依赖?

在之前的例子中,你可能已经注意有一个dependencies元素。实际上你一直在使用一个外部的依赖,但是现在我们讨论一些其工作的细节。想深入了解,请查看依赖机制介绍 dependencies小结列出了所有在项目构建过程(无论是变异期、测试期、运行期或者其他)中需要的外部依赖。现在我们的项目只依赖JUnit(为了清晰,我将所有的关于资源的东西都提取出来):

<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>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project>

对于每个外部一拉,你需要定义至少四个东西:groupId,artifactId,versionscope,groupId,artifactIdversion和上边介绍的pom.xml是一样的。scope元素表明你的项目怎样使用此依赖,值可以是compile,testruntime。要了解更多的信息,你可以指定一个依赖,并查看项目描述符参考 根据这个依赖信息,Maven能够在构建项目是引用依赖Maven从哪里引用依赖呢?Maven会从你的本地仓库中寻找所有的依赖。在之前的章节,我们将artifact(my-app-1.0-SNAPSHOT.jar)安装到了本地仓库.一旦被安装到了本地仓库,另外一个项目也可以引用这个jar文件作为依赖,只需像之前那样讲依赖信息添加到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">
  <groupId>com.mycompany.app</groupId>
  <artifactId>my-other-app</artifactId>
  ...
  <dependencies>
    ...
    <dependency>
      <groupId>com.mycompany.app</groupId>
      <artifactId>my-app</artifactId>
      <version>1.0-SNAPSHOT</version>
      <scope>compile</scope>
    </dependency>
  </dependencies>
</project>

假如依赖在其他地方使用呢?他们怎样来访问我的本地仓库呢?当一个项目引用依赖在本地仓库不可得是,Maven将会从远程仓库下载依赖到本地仓库。你可能注意到maven下载了许多东西在你勾线你的第一个项目的时候(折现下载的依赖是一些用于构建项目的插件)。默认远程仓库是http://repo.maven.apache.org/maven2/。你同样可以建立自己的远程仓库(可能是你公司的中央仓库)用于替换默认的远程仓库,或者增加一个。了解更多关于仓库的信息你可以引用仓库介绍。 让我们添加另外一个依赖到我们的项目。现在我们增加以下日志到代码并且需要增加log4j作为一个依赖。首先我们需要知道log4j的groupId,artifactId以及version等信息。我们可以浏览ibiblio找到这些,或者利用google搜索site:www.ibiblio.org maven2 log4j。搜索会给你展示一个目录/maven2/log4j/log4j或者/pub/packages/maven2/log4j/log4j。在这个目录下有一个文件叫作maven-metadata.xml。这里是log4j的maven-meatdata.xml

<metadata>
  <groupId>log4j</groupId>
  <artifactId>log4j</artifactId>
  <version>1.1.3</version>
  <versioning>
    <versions>
      <version>1.1.3</version>
      <version>1.2.4</version>
      <version>1.2.5</version>
      <version>1.2.6</version>
      <version>1.2.7</version>
      <version>1.2.8</version>
      <version>1.2.11</version>
      <version>1.2.9</version>
      <version>1.2.12</version>
    </versions>
  </versioning>
</metadata>
|-- META-INF
|   |-- MANIFEST.MF
|   |-- application.properties
|   `-- maven
|       `-- com.mycompany.app
|           `-- my-app
|               |-- pom.properties
|               `-- pom.xml
`-- com
    `-- mycompany
        `-- app
            `-- App.class

你可以看到${basedir}/src/main/resources可以在jar文件的根目录下找到,并且在META-INF目录下可以找到application.properties。你同样会注意到一些其他的文件比如META-INF/MANIFEST.MFpom.xmlpom.properties,这些事Maven默认生成的文件。你可以创建你自己的manifest,如果你不创建,Maven会默认创建一个(你同样可以改变默认的manifest,我们将会在一会说到这个)。pom.xmlpom.properties文件被打包到jar中,因此每个artifact都是独立的,如果你需要的话,你可以利用你自己应用的元数据。一个简单的应用就是可以恢复你应用的版本号。配置文件POM需要你利用一些Maven工具,但是properties可以利用java api,比如:

#Generated by Maven
#Tue Oct 04 15:43:21 GMT-05:00 2005
version=1.0-SNAPSHOT
groupId=com.mycompany.app
artifactId=my-app

为将资源文件为你的单元测试加载到类路径下,你需要遵循与你添加资源文件到jar中同样的模式,这是你应该拥有一个项目目录结构类似下边:

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

Maven项目,所需做的就是添加或重新配置插件。 Maven 1.0的用户请注意:在Maven1.0中,你可能会添加一些preGoal到maven.xml并且在project.properties中添加一些条目。这里有些变化。

比如,我们将会配置java编译器能够编译jdk 5.0的代码,只需在你的POM中如下配置即可:

<build>
  <plugins>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-compiler-plugin</artifactId>
      <version>3.3</version>
      <configuration>
        <source>1.5</source>
        <target>1.5</target>
      </configuration>
    </plugin>
  </plugins>
</build>

你会注意所有的Maven插件都在某种程度上类似依赖,插件会自动的下载和使用,而且是一个确定的版本。 configuration元素会将给定的参数应用到每个目标。在以上的案例中,编译插件被作为构建过程的一部分,也可以在过程中添加新的目标并配置指定的目标。想了解更多的信息,请看生命周期构建简介 想查看什么配置适合一个插件,你可以看插件列表并导航到你在使用的插件和目标。对于怎样配置插件的合适参数,可以查看插件配置指南

我如何将资源添加到jar文件当中?

另外一个很常用的案例是不需要做任何POM改变,可以将资源我文件打包到Jar文件当中。对于这个功能,Maven需要依赖标准的目录结构,意思是利用标准的Maven约定将资源放在约定的目录结构,你可以将资源打包到jar文件。 看下边的例子,我们可以将想打包的资源文件放在目录${basedir}/src/main/resources。这个简单的规则是说:任何在{basedir}/src/main/resources目录下的目录或文件都会打包到你的jar文件中,而且目录结构也是一样的,基目录的jar文件的根目录。

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目录中有文件appllication.properties。如果你解包jar文件,你可以看到类似如下:

从这个文件里,我们可以看到groupId为log4j并且artifactId为log4j。我们有不多的版本可以进行选择;现在我们用罪行的版本,1.2.12(一些maven-metadata.xml文件可能指定哪个版本是最新的发布版本)。在目录下我们还可以看到每个版本的log4j库。在里边,我们可以看到jar文件(比如log4j-1.2.12.jar)和一个pom文件(这个是依赖的pom文件,表明它拥有的更多的依赖和其他信息)以及另外一个maven-metadata.xml文件。这里还有一个md5文件包含这些文件的MD5哈希值。你可以用这个去验证一个库或者知道你现在正在使用的库的版本号。 现在我们知道我们需要的信息,我们可以吧依赖添加到我们的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>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>log4j</groupId>
      <artifactId>log4j</artifactId>
      <version>1.2.12</version>
      <scope>compile</scope>
    </dependency>
  </dependencies>
</project>



网易云新用户大礼包:https://www.163yun.com/gift

本文来自网易实践者社区,经作者范鹏程授权发布。