Maven详解
Maven介绍
前因,先了解一个java项目的构成。
- 首先,要确定引入哪些依赖包。比如需要log4j,就把log4j相关jar包放入classpath中。
- 其次,要确定项目的目录结构。源码,配置文件,编译生成的.class文件该存放在哪。
- 最后,除了用集成开发工具(idea)编译外,还必须通过命令行工具编译,才能让项目在独立服务器上编译,测试,部署。
这些工作琐碎耗时,这时候就需要一个标准化java项目管理和构建工具。
Maven就是是专门为Java项目打造的管理和构建工具,它的主要功能有:
- 提供了一套标准化的项目结构;
- 提供了一套标准化的构建流程(编译,测试,打包,发布……);
- 提供了一套依赖管理机制。
Maven安装
idea已经集成了Maven,直接用就好。
如果自己下载需要配置环境变量。
Maven仓库
仓库就是存放依赖和插件的地方,Maven如何知道从何处下载所需的依赖?也就是相关的jar包?答案是Maven维护了一个中央仓库(repo1.maven.org),所有第三方库将自身的jar以及相关信息上传至中央仓库,Maven就可以从中央仓库把所需依赖下载到本地。
Maven并不会每次都从中央仓库下载jar包。一个jar包一旦被下载过,就会被Maven自动缓存在本地目录(用户主目录的.m2目录),所以,除了第一次编译时因为下载需要时间会比较慢,后续过程因为有本地缓存,并不会重复下载相同的jar包。
Maven 仓库的分类:
-
本地仓库 ,默认在c/users/username/.m/下。
-
远程仓库,在远程仓库中又分成了3种:
-
中央仓库
- 镜像仓库,如阿里云的maven镜像,定期从中央仓库同步
-
私服
-
其它公共库
-
中央库和镜像库:
slow ┌───────────────────┐
┌─────────────>│Maven Central Repo.│
│ └───────────────────┘
│ │
│ │sync
│ ▼
┌───────┐ fast ┌───────────────────┐
│ User │─────────>│Maven Mirror Repo. │
└───────┘ └───────────────────┘
中国区用户可以使用阿里云提供的Maven镜像仓库。使用Maven镜像仓库需要一个配置,在用户主目录下进入.m2目录,创建一个settings.xml配置文件,内容如下:
<settings>
<mirrors>
<mirror>
<id>aliyun</id>
<name>aliyun</name>
<mirrorOf>central</mirrorOf>
<!-- 国内推荐阿里云的Maven镜像 -->
<url>https://maven.aliyun.com/repository/central</url>
</mirror>
</mirrors>
</settings>
Maven项目结构
一个使用Maven管理的普通的Java项目,它的目录结构默认如下:
a-maven-project
├── pom.xml
├── src
│ ├── main
│ │ ├── java
│ │ └── resources
│ └── test
│ ├── java
│ └── resources
└── target
项目的根目录a-maven-project是项目名,它有一个项目描述文件pom.xml,存放Java源码的目录是src/main/java,存放资源文件的目录是src/main/resources,存放测试源码的目录是src/test/java,存放测试资源的目录是src/test/resources,最后,所有编译、打包生成的文件都放在target目录里。这些就是一个Maven项目的标准目录结构。
所有的目录结构都是约定好的标准结构,我们千万不要随意修改目录结构。使用标准结构不需要做任何配置,Maven就可以正常使用。
Maven构建流程
Maven不但有标准化的项目结构,而且还有一套标准化的构建流程,可以自动化实现编译,打包,发布,等等。
Lifecycle和Phase
使用Maven时,我们首先要了解什么是Maven的生命周期(lifecycle)。
Maven的生命周期由一系列阶段(phase)构成,以内置的生命周期default为例,它包含以下phase:
Default Lifecycle
- validate 验证工程是否正确,所需的信息是否完整
- initialize 初始化构建平台,例如:设置properties或创建目录
- generate-sources
- process-sources
- generate-resources
- process-resources 复制并处理资源文件,至目标目录,准备打包
- compile 编译源代码
- process-classes 源码编译后的后期处理,比如java字节码的增强(优化?)
- generate-test-sources
- process-test-sources
- generate-test-resources
- process-test-resources
- test-compile 编译测试源代码(默认是test目录下)
- process-test-class
- test 执行单元测试
- prepare-package
- package 将工程文件打包为指定的格式,例如JAR,WAR等
- pre-integration-test
- integration-test 集成测试
- post-integration-test
- verify 检查package是否有效、符合标准
- install 将包安装至本地仓库,以让其它项目依赖。
- deploy 将最终的包复制到远程的仓库,以让其它开发人员与项目共享。
如果我们运行mvn package,Maven就会执行default生命周期,它会从开始一直运行到package这个phase为止:
- validate
- ...
- package
Maven另一个常用的生命周期是clean,它会执行3个phase:
- pre-clean
- clean (注意这个clean不是lifecycle而是phase)
- post-clean
所以,我们使用mvn这个命令时,后面的参数是phase,Maven自动根据生命周期运行到指定的phase。
更复杂的例子是指定多个phase,例如,运行mvn clean package,Maven先执行clean生命周期并运行到clean这个phase,然后执行default生命周期并运行到package这个phase,实际执行的phase如下:
- pre-clean
- clean (注意这个clean是phase)
- validate
- ...
- package
在实际开发过程中,经常使用的命令有:
mvn clean:清理所有生成的class和jar;
mvn clean compile:先清理,再执行到compile;
mvn clean test:先清理,再执行到test,因为执行test前必须执行compile,所以这里不必指定compile;
mvn clean package:先清理,再执行到package。
大多数phase在执行过程中,因为我们通常没有在pom.xml中配置相关的设置,所以这些phase什么事情都不做。
经常用到的phase其实只有几个:
- clean:清理
- compile:编译
- test:运行测试
- package:打包
Goal
执行一个phase又会触发一个或多个goal:
| 执行的Phase | 对应执行的Goal |
|---|---|
| compile | compiler:compile |
| test | compiler:testCompile surefire:test |
goal的命名总是abc:xyz这种形式。
看到这里,相信大家对lifecycle、phase和goal已经明白了吧?
其实我们类比一下就明白了:
- lifecycle相当于Java的package,它包含一个或多个phase;
- phase相当于Java的class,它包含一个或多个goal;
- goal相当于class的method,它其实才是真正干活的。
大多数情况,我们只要指定phase,就默认执行这些phase默认绑定的goal,只有少数情况,我们可以直接指定运行一个goal,例如,启动Tomcat服务器:
mvn tomcat:run
小结
Maven通过lifecycle、phase和goal来提供标准的构建流程。Maven构建项目就是执行lifecycle,执行到指定的phase为止。每个phase会执行自己默认的一个或多个goal。goal是最小任务单元。
最常用的构建命令是指定phase,然后让Maven执行到指定的phase:
- mvn clean
- mvn clean compile
- mvn clean test
- mvn clean package
通常情况,我们总是执行phase默认绑定的goal,因此不必指定goal。
项目模块管理
在软件开发中,把一个大项目分拆为多个模块是降低软件复杂度的有效方法:
┌ ─ ─ ─ ─ ─ ─ ┐
┌─────────┐
│ │Module A │ │
└─────────┘
┌──────────────┐ split │ ┌─────────┐ │
│Single Project│───────> │Module B │
└──────────────┘ │ └─────────┘ │
┌─────────┐
│ │Module C │ │
└─────────┘
└ ─ ─ ─ ─ ─ ─ ┘
对于Maven工程来说,原来是一个大项目:
single-project
├── pom.xml
└── src
现在可以分拆成3个模块:
mutiple-project
├── module-a
│ ├── pom.xml
│ └── src
├── module-b
│ ├── pom.xml
│ └── src
└── module-c
├── pom.xml
└── src
Maven可以有效地管理多个模块,我们只需要把每个模块当作一个独立的Maven项目,它们有各自独立的pom.xml。
提取共同部分作parent
parent的<packaging>是pom而不是jar,因为parent本身不含任何Java代码。编写parent的pom.xml只是为了在各个模块中减少重复的配置。现在我们的整个工程结构如下:
multiple-project
├── pom.xml (我在idea中不需要)
├── parent
│ └── pom.xml
├── module-a
│ ├── pom.xml
│ └── src
├── module-b
│ ├── pom.xml
│ └── src
└── module-c
├── pom.xml
└── src
小结
Maven支持模块化管理,可以把一个大项目拆成几个模块:
- 可以通过继承在parent的
pom.xml统一定义重复配置; - 可以通过
<modules>编译多个模块。
Maven项目的pom文件
超级pom
在Maven中定义了超级pom.xml,任何没有申明自己父pom.xml的pom.xml都将默认继承自这个超级pom.xml。文件为pom-4.0.0.xml,后文pom之间的关系里有说明。
超级pom.xml的位置:
Maven 2.xxx版本:在maven安装目录下的maven2/lib/maven-xxx-uber.jar中,org.apache.maven.project下会有pom-4.0.0.xml的文件。
Maven 3.xxx版本: 在maven安装目录下的maven3/lib/maven-model-builder-xxx.jar中, \org\apache\maven\mode目录中的pom-4.0.0.xml。
先来看一下这个超级pom.xml的定义:
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
<!-- START SNIPPET: superpom -->
<project>
<modelVersion>4.0.0</modelVersion>
<repositories>
<repository>
<id>central</id>
<name>Central Repository</name>
<url>https://repo.maven.apache.org/maven2</url>
<layout>default</layout>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>central</id>
<name>Central Repository</name>
<url>https://repo.maven.apache.org/maven2</url>
<layout>default</layout>
<snapshots>
<enabled>false</enabled>
</snapshots>
<releases>
<updatePolicy>never</updatePolicy>
</releases>
</pluginRepository>
</pluginRepositories>
<build>
<directory>${project.basedir}/target</directory>
<outputDirectory>${project.build.directory}/classes</outputDirectory>
<finalName>${project.artifactId}-${project.version}</finalName>
<testOutputDirectory>${project.build.directory}/test-classes</testOutputDirectory>
<sourceDirectory>${project.basedir}/src/main/java</sourceDirectory>
<scriptSourceDirectory>${project.basedir}/src/main/scripts</scriptSourceDirectory>
<testSourceDirectory>${project.basedir}/src/test/java</testSourceDirectory>
<resources>
<resource>
<directory>${project.basedir}/src/main/resources</directory>
</resource>
</resources>
<testResources>
<testResource>
<directory>${project.basedir}/src/test/resources</directory>
</testResource>
</testResources>
<pluginManagement>
<!-- NOTE: These plugins will be removed from future versions of the super POM -->
<!-- They are kept for the moment as they are very unlikely to conflict with lifecycle mappings (MNG-4453) -->
<plugins>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.3</version>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2-beta-5</version>
</plugin>
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.8</version>
</plugin>
<plugin>
<artifactId>maven-release-plugin</artifactId>
<version>2.3.2</version>
</plugin>
</plugins>
</pluginManagement>
</build>
<reporting>
<outputDirectory>${project.build.directory}/site</outputDirectory>
</reporting>
<profiles>
<!-- NOTE: The release profile will be removed from future versions of the super POM -->
<profile>
<id>release-profile</id>
<activation>
<property>
<name>performRelease</name>
<value>true</value>
</property>
</activation>
<build>
<plugins>
<plugin>
<inherited>true</inherited>
<artifactId>maven-source-plugin</artifactId>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<inherited>true</inherited>
<artifactId>maven-javadoc-plugin</artifactId>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<inherited>true</inherited>
<artifactId>maven-deploy-plugin</artifactId>
<configuration>
<updateReleaseInfo>true</updateReleaseInfo>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
<!-- END SNIPPET: superpom -->
前面说到一个pom.xml来说有几个元素是必须定义的,一个是project根元素,然后就是它里面的modelVersion、groupId、artifactId和version。由上面的超级pom.xml的内容我们可以看到pom.xml中没有groupId、artifactId和version的定义,所以我们在建立自己的pom.xml的时候就需要定义这三个元素。和java里面的继承类似,子pom.xml会完全继承父pom.xml中所有的元素,而且对于相同的元素,一般子pom.xml中的会覆盖父pom.xml中的元素,但是有几个特殊的元素它们会进行合并而不是覆盖。这些特殊的元素是:
- dependencies
- developers 开发者,和功能无关
- contributors 贡献者,和功能无关
- build下的plugin列表,包括plugin下面的reports
- build下的resources
项目pom
下面示例是maven项目中的pom.xml文件。注意,其中的modelVersion是4.0.0,这是当前仅有可以被Maven2&3同时支持的POM版本。
<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>
<!-- 基本设置 The Basics -->
<groupId>...</groupId>
<artifactId>...</artifactId>
<version>...</version>
<packaging>...</packaging>
<dependencies>...</dependencies>
<parent>...</parent>
<dependencyManagement>...</dependencyManagement>
<modules>...</modules>
<properties>...</properties>
<!-- 构建过程的设置 Build Settings -->
<build>...</build>
<reporting>...</reporting>
<!-- 项目信息设置 More Project Information -->
<name>...</name>
<description>...</description>
<url>...</url>
<inceptionYear>...</inceptionYear>
<licenses>...</licenses>
<organization>...</organization>
<developers>...</developers>
<contributors>...</contributors>
<!-- 环境设置 Environment Settings -->
<issueManagement>...</issueManagement>
<ciManagement>...</ciManagement>
<mailingLists>...</mailingLists>
<scm>...</scm>
<prerequisites>...</prerequisites>
<repositories>...</repositories>
<pluginRepositories>...</pluginRepositories>
<distributionManagement>...</distributionManagement>
<profiles>...</profiles>
</project>
一个最简单的pom.xml的定义必须包含modelVersion、groupId、artifactId和version这四个元素,当然这其中的元素也是可以从它的父项目中继承的。
<?xml version="1.0" encoding="UTF-8"?>
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<!--
含义:组织标识,定义了项目属于哪个组,风向标,坐标,或者说若把本项目打包
用途:此名称则是本地仓库中的路径,列如:otowa.user.dao,在M2_REPO目录下,将是: otowa/user/dao目录
命名规范:项目名称,模块,子模块
-->
<groupId>otowa.user.dao</groupId>
<!--
含义:项目名称也可以说你所模块名称,定义当面Maven项目在组中唯一的ID
用途:例如:user-dao,在M2_REPO目录下,将是:otowa/user/dao/user-dao目录
命名规范:唯一就好
-->
<artifactId>user-dao</artifactId>
<!--
含义:项目当前的版本号
用途:例如:0.0.1-SNAPSHOT,在M2_REPO目录下,将是:otowa/user/dao/user-dao/0.0.1- SNAPSHOT目录
-->
<version>0.0.1-SNAPSHOT</version>
<!-- 打包的格式,可以为:pom , jar , maven-plugin , ejb , war , ear , rar , par -->
<packaging>war</packaging>
<!-- 元素声明了一个对用户更为友好的项目名称 -->
<name>maven</name>
</project>
碰上非开源包,maven支持不了这个包,那么则有有三种 方法处理:
- 本地安装这个插件install plugin
- 创建自己的repositories并且部署这个包。
- 设置scope为system,并且指定系统路径。
对于某个依赖,Maven只需要3个变量即可唯一确定某个jar包:
- groupId:属于组织的名称,类似Java的包名;
- artifactId:该jar包自身的名称,类似Java的类名;
- version:该jar包的版本。
通过上述3个变量,即可唯一确定某个jar包。Maven通过对jar包进行PGP签名确保任何一个jar包一经发布就无法修改。修改已发布jar包的唯一方法是发布一个新版本。
因此,某个jar包一旦被Maven下载过,即可永久地安全缓存在本地。
注:只有以-SNAPSHOT结尾的版本号会被Maven视为开发版本,开发版本每次都会重复下载,这种SNAPSHOT版本只能用于内部私有的Maven repo,公开发布的版本不允许出现SNAPSHOT。
多模块项目pom的继承
通过idea的多模块管理进行测验:
建立empty project,在project中再建立maven module。
父工程的packaging的标签值必须为pom。
父工程下的目录结构只有一个pom.xml文件(idea自己的配置文件不算)
父工程module-p的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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.cijian.maven</groupId>
<artifactId>module-p</artifactId>
<version>1.0.0</version>
<packaging>pom</packaging>
</project>
子工程maven-01,需要继承父工程module-p,子工程必须指明父工程的groupId、artifactId和version。
可以这样定义maven-01的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/maven-v4_0_0.xsd">
<parent>
<groupId>com.cijian.maven</groupId>
<artifactId>module-p</artifactId>
<version>1.0.0</version>
<relativePath>../projectA/pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>maven-01</artifactId>
<!--默认是jar,可省略 -->
<packaging>jar</packaging>
</project>
pom中dependency设置说明:
依赖关系列表(dependency list)是POM的重要部分
项目之间的依赖是通过pom.xml文件里面的dependencies元素下面的dependency元素进行的。一个dependency元素定义一个依赖关系。在dependency元素中我们主要通过依赖项目的groupId、artifactId和version来定义所依赖的项目。
先来看一个简单的项目依赖的示例吧,假设我现在有一个项目projectA,然后它里面有对junit的依赖,那么它的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.tiantian.mavenTest</groupId>
<artifactId>projectB</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
<optional>true</optional>
</dependency>
</dependencies>
</project>
groupId, artifactId, version:描述了依赖的项目唯一标志。
type:对应于依赖项目的packaging类型,默认是jar。
scope:用于限制相应的依赖范围、传播范围。scope的主要取值范围如下(还有一个是在Maven2.0.9以后版本才支持的import,关于import作用域将在后文《Dependency介绍》中做介绍):
-
test:在测试范围有效,它在执行命令test的时候才执行,并且它不会传播给其他模块进行引入,比如 junit,dbunit 等测试框架。
-
compile(default 默认):这是它的默认值,这种类型很容易让人产生误解,以为只有在编译的时候才是需要的,其实这种类型表示所有的情况都是有用的,包括编译和运行时。而且这种类型的依赖性是可以传递的。
-
runtime:在程序运行的时候依赖,在编译的时候不依赖,比如mysql的jdbc。
-
provided:这个跟compile很类似,但是它表示你期望这个依赖项目在运行时由JDK或者容器来提供。这种类型表示该依赖只有在测试和编译的情况下才有效,在运行时将由JDK或者容器提供。这种类型的依赖性是不可传递的。比如 javaee:
- eclipse开发web环境中是没有javaee必须要手动添加。
- myeclipse新建web项目会有JavaEE(servlet-api.jar,jsp-api.jar...)web容器依赖的jar包,一般都是做开发的时候才使用。但是myeclipse不会把这些 jar包发布的,lib下你是找不到javaee引入的jar包,因为myeclipse发布项目的时候会忽略它。为什么?因为tomcat容器bin/lib已经存在了这个jar包了。
-
system:这种类型跟provided类似,唯一不同的就是这种类型的依赖我们要自己提供jar包,这需要与另一个元素systemPath来结合使用。systemPath将指向我们系统上的jar包的路径,而且必须是给定的绝对路径。
-
systemPath:上面已经说过了这个元素是在scope的值为system的时候用于指定依赖的jar包在系统上的位置的,而且是绝对路径。该元素必须在依赖的 jar包的scope为system时才能使用,否则Maven将报错。
-
optional:当该项目本身作为其他项目的一个依赖时标记该依赖为可选项。假设现在projectA有一个依赖性projectB,我们把projectB这个依赖项设为optional,这表示projectB在projectA的运行时不一定会用到。这个时候如果我们有另一个项目projectC,它依赖于projectA,那么这个时候因为projectB对于projectA是可选的,所以Maven在建立projectC的时候就不会安装projectB,这个时候如果projectC确实需要使用到projectB,那么它就可以定义自己对projectB的依赖。当一个依赖是可选的时候,我们把optional元素的值设为true,否则就不设置optional元素。
-
exclusions:考虑这样一种情况,我们的projectA依赖于projectB,然后projectB又依赖于projectC,但是在projectA里面我们不需要projectB依赖的projectC,那么这个时候我们就可以在依赖projectB的时候使用exclusions元素下面的exclusion排除projectC。这个时候我们可以这样定义projectA对projectB的依赖:
<dependencies> <dependency> <groupId>com.tiantian.mavenTest</groupId> <artifactId>projectB</artifactId> <version>1.0-SNAPSHOT</version> <exclusions> <exclusion> <groupId>com.tiantian.mavenTest</groupId> <artifactId>projectC</artifactId> </exclusion> </exclusions> </dependency> </dependencies>
-
pom中build设置说明:
defaultGoal:默认的目标,必须跟命令行上的参数相同,如:jar:jar,或者与时期parse相同,例如install
directory:指定build target目标的目录,默认为$(basedir}/target,即项目根目录下的target
finalName:指定去掉后缀的工程名字,例如:默认为\({artifactId}-\){version}
filters:用于定义指定filter属性的位置,例如filter元素赋值filters/filter1.properties,那么这个文件里面就可以定义name=value对,这个name=value对的值就可以在工程pom中通过\({name}引用,默认的filter目录是\){basedir}/src/main/fiters/ 。
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>
- targetPath:指定build资源到哪个目录,默认是base directory
- filtering:指定是否将filter文件(即上面说的filters里定义的*.property文件)的变量值在这个resource文件有效,例如上面就指定那些变量值在configuration文件无效。
- directory:指定属性文件的目录,build的过程需要找到它,并且将其放到targetPath下,默认的directory是${basedir}/src/main/resources
- includes:指定包含文件的patterns,符合样式并且在directory目录下的文件将会包含进project的资源文件。
- excludes:指定不包含在内的patterns,如果inclues与excludes有冲突,那么excludes胜利,那些符合冲突的样式的文件是不会包含进来的。
- testResources:这个模块包含测试资源元素,其内容定义与resources类似,不同的一点是默认的测试资源路径是${basedir}/src/test/resources,测试资源是不部署的。
plugins配置:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.0</version>
<extensions>false</extensions>
<inherited>true</inherited>
<configuration>
<classifier>test</classifier>
</configuration>
<dependencies>...</dependencies>
<executions>...</executions>
</plugin>
pluginManagement:
<pluginManagement>与<plugins>并列,两者之间的关系类似于<dependencyManagement>与<dependencies>之间的关系。<pluginManagement>中也配置<plugin>,其配置参数与<plugins>中的<plugin>完全一致。只是,<pluginManagement>往往出现在父项目中,其中配置的<plugin>往往通用于子项目。子项目中只要在<plugins>中以<plugin>声明该插件,该插件的具体配置参数则继承自父项目中<pluginManagement>对该插件的配置,从而避免在子项目中进行重复配置。
pom中其它参数设置说明:
dependencyManagement:
是用于帮助管理chidren的dependencies的。例如如果parent使用dependencyManagement定义了一个dependencyon junit:junit4.0,那么 它的children就可以只引用 groupId和artifactId,而version就可以通过parent来设置,这样的好处就是可以集中管理 依赖的详情
modules:对于多模块的project,outer-module没有必需考虑inner-module的dependencies,当列出modules的时候,modules的顺序是不重要的,因为maven会自动根据依赖关系来拓扑排序。
properties:是用来定义一些配置属性,例如设置编码,版本号等。
reporting设置:reporting包含site生成阶段的一些元素,某些maven plugin可以生成reports并且在reporting下配置。例如javadoc,maven site等,在reporting下配置的report plugin的方法与build几乎一样,最不同的是build的plugin goals在executions下设置,而reporting的configures goals在reporttest。
name:项目除了artifactId外,可以定义多个名称
description: 项目描述
url:项目url
inceptionYear:创始年份
等略...
pom引用属性
在pom.xml文件中我们可以使用\({propertyName}的形式引用属性。是值的占位符,类似EL,类似ant的属性,比如\){X},可用于pom文件任何赋值的位置。有以下分类:
- env.propertyName:这种形式表示引用的是环境变量,比如我们需要引用当前系统的环境变量PATH的时候,就可以使用${env.PATH}。
- project.propertyName:这种形式表示引用的是当前这个pom.xml中project根元素下面的子元素的值。比如我们需要引用当前project下面的version的时候,就可以使用${project.version}。
- settings.propertyName:这种形式引用的是Maven本地配置文件settings.xml或本地Maven安装目录下的settings.xml文件根元素settings下的元素。比如我们需要引用settings下的本地仓库localRepository元素的值时,我们可以用$
- Java System Properties:java的系统属性,所有在java中使用java.lang.System.getProperties()能够获取到的属性都可以在pom.xml中引用,比如${java.home}。
- 自定义:pom.xml中properties元素下面的子元素作为属性。假如在pom.xml中有如下一段代码
<hello.world>helloWorld</hello.world> ,那么我们就可以使用${hello.world}引用到对应的helloWorld。
Maven常用的插件
- maven-shade-plugin:打包所有依赖包并生成可执行jar;
- cobertura-maven-plugin:生成单元测试覆盖率报告;
- findbugs-maven-plugin:对Java源码进行静态分析以找出潜在问题。

浙公网安备 33010602011771号