Maven
Apache Maven is a software project management and comprehension tool. Based on the concept of a project object model(POM), Maven can manage a project’s build, reporting and documentation from a central piece of information.
参考文档: Maven Documentation
Maven概述
一个基本的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 >
< groupId > com . mycompany . app </ groupId >
< artifactId > my - app </ artifactId >
< packaging > jar </ packaging >
< version > 1.0 - SNAPSHOT </ version >
< 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 >
Pom文件是面向工程的一个管理模型,全称是Project Object Model。这个Pom文件中包含的基本内容有:
project pom文件的顶层元素
modelVersion Pom对象模型的版本
groupId 是创建这个项目的组织或部门的唯一标志,比如说org.apache.maven.plugins
就是所有Maven plugins的groupId
artifactId 是这个项目生成结果的唯一标志,Maven生成结果的命名模式为<artifactId>-<version>.<extension>
,比如说my app-1.0.jar
packaging 这个参数表明了项目生成结果的打包模式,比如JAR,WAR,EAR等,同时这个参数还表明了build过程采用的特定生命周期
version 这个参数表明了项目生成结果的版本,在version里经常会看到SNAPSHOT标志,它表明了项目处于开发阶段。
name 这个参数代表项目的展示名字,通常作用在Maven生成的文档中
url 这个参数代表哪里可以找到该项目,通常作用在Maven生成的文档中
description 这个参数描述了项目的基本信息,通常作用在Maven生成的文档中
Maven项目的基本结构
my - app
|-- pom . xml
` -- src
|-- main
| ` -- java
| ` -- com
| ` -- mycompany
| ` -- app
| ` -- App . java
` -- test
` -- java
` -- com
` -- mycompany
` -- app
` -- AppTest . java
上面是一个Maven项目的基本结构,项目的相关资源位于${basedir}/src/main/java
中,而测试的资源位于${basedir}/src/test/java
中,而pom文件位于pom.xml
中。
Maven的执行
1. mvn compile
执行mvn compile
,编译的结果会默认放在${basedir}/target/classes
目录下。
2. mvn test
执行mvn test
,会执行${basedir}/src/test/java
中的单元测试。如果只想编译测试代码而不执行,则执行mvn test-compile
。
3. mvn package
执行mvn package
会对项目进行打包,假如当前在pom中的packaging设定为jar,那么执行该命令后会在${basedir}/target
目录下生成对应的jar包。
4. mvn install
如果想把mvn package
生成的Jar文件安装在本地库中以让其它项目引用,则可以执行mvn install
命令,将生成的jar包放在${user.home}/.m2/repository
中。
Plugins
Plugins用来定制Maven项目的编译过程,假如要配置Java Compiler允许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 >
<configuration>
中的配置会应用在对应Plugin的所有Goal。
资源文件打包
${basedir}/src/main/resources
目录下的所有文件都会被打包到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
| |-- MANIFEST . MF
| |-- application . properties
| ` -- maven
| ` -- com . mycompany . app
| ` -- my - app
| |-- pom . properties
| ` -- pom . xml
` -- com
` -- mycompany
` -- app
` -- App . class
文件过滤
Maven支持文件过滤的功能,可以在build时候为文件提供变量赋值,比如说上面的application.properties
文件中有如下定义:
# application . properties
application . name = $ { project . name }
application . version = $ { project . version }
那么需要在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 >
< 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 >
执行mvn process-resources
命令后,在target/classes
下找到application.properties
可以看到如下结果:
# application . properties
application . name = Maven Quick Start Archetype
application . version = 1.0 - SNAPSHOT
可见其中形如${<property name>}
的变量已经被替换成了对应的值,如果要引入其它文件中定义的属性,只需要在pom文件中定义<filters>
,比如:
< build >
< filters >
< filter > src / main / filters / filter . properties </ filter >
</ filters >
< resources >
< resource >
< directory > src / main / resources </ directory >
< filtering > true </ filtering >
</ resource >
</ resources >
</ build >
那么Maven会先读出filter.properties
中的属性,然后把这些属性注入对应的resources中。
Dependencies
<dependencies>
标签下列出了所有的外部依赖,比如下面的Pom文件添加了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 >
<dependency>
的<scope>
标签的值可以为compile,test和runtime,当Maven编译项目时,它首先会在${user.home}/.m2/repository
这个本地库目录下寻找所需的依赖,如果没有会去远程的库上寻找,并将其下载到本地库中,默认的远程库地址为http://repo.maven.apache.org/maven2/
。
包的发布
当需要发布一个包的远程仓库时,需要配置库的地址和相应的权限,一个范例如下:
< 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 > org . apache . codehaus . plexus </ groupId >
< artifactId > plexus - utils </ artifactId >
< version > 1.0 . 4 </ version >
</ dependency >
</ dependencies >
< build >
< filters >
< filter > src / main / filters / filters . properties </ filter >
</ filters >
< resources >
< resource >
< directory > src / main / resources </ directory >
< filtering > true </ filtering >
</ resource >
</ resources >
</ build >
<!--
|
|
|
-->
< distributionManagement >
< repository >
< id > mycompany - repository </ id >
< name > MyCompany Repository </ name >
< url > scp: //repository.mycompany.com/repository/maven2</url>
</ repository >
</ distributionManagement >
</ project >
它所需要的权限配置在settings.xml
中:
< settings xmlns = "http://maven.apache.org/SETTINGS/1.0.0"
xmlns: xsi = "http://www.w3.org/2001/XMLSchema-instance"
xsi: schemaLocation = "http://maven.apache.org/SETTINGS/1.0.0
http://maven.apache.org/xsd/settings-1.0.0.xsd" >
...
< servers >
< server >
< id > mycompany - repository </ id >
< username > jvanzyl </ username >
<!-- Default value is ~/. ssh / id_dsa -->
< privateKey >/ path / to / identity </ privateKey > ( default is ~/. ssh / id_dsa )
< passphrase > my_key_passphrase </ passphrase >
</ server >
</ servers >
...
</ settings >
多Modules管理
Maven很好的支持了多个Modules的管理,假如一个Maven项目结构如下:
+- pom . xml
+- my - app
| +- pom . xml
| +- src
| +- main
| +- java
+- my - webapp
| +- pom . xml
| +- src
| +- main
| +- webapp
对于根目录下的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 >
< groupId > com . mycompany . app </ groupId >
< artifactId > app </ artifactId >
< version > 1.0 - SNAPSHOT </ version >
< packaging > pom </ packaging >
< modules >
< module > my - app </ module >
< module > my - webapp </ module >
</ modules >
</ project >
其中的<modules>
定义了其管理的两个子modules。
假如my-webapp需要依赖my-app包,那么在my-webapp/pom.xml
中增加:
...
< dependencies >
< dependency >
< groupId > com . mycompany . app </ groupId >
< artifactId > my - app </ artifactId >
< version > 1.0 - SNAPSHOT </ version >
</ dependency >
...
</ dependencies >
然后在my-app和my-webapp的pom文件中都增加parent配置:
< 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" >
< parent >
< groupId > com . mycompany . app </ groupId >
< artifactId > app </ artifactId >
< version > 1.0 - SNAPSHOT </ version >
</ parent >
...
然后在最顶层目录下执行mvn clean install
,会创建my-webapp/target/my-webapp.war
,其中包含:
$ jar tvf my - webapp / target / my - webapp - 1.0 - SNAPSHOT . war
0 Fri Jun 24 10 : 59 : 56 EST 2005 META - INF /
222 Fri Jun 24 10 : 59 : 54 EST 2005 META - INF / MANIFEST . MF
0 Fri Jun 24 10 : 59 : 56 EST 2005 META - INF / maven /
0 Fri Jun 24 10 : 59 : 56 EST 2005 META - INF / maven / com . mycompany . app /
0 Fri Jun 24 10 : 59 : 56 EST 2005 META - INF / maven / com . mycompany . app / my - webapp /
3239 Fri Jun 24 10 : 59 : 56 EST 2005 META - INF / maven / com . mycompany . app / my - webapp / pom . xml
0 Fri Jun 24 10 : 59 : 56 EST 2005 WEB - INF /
215 Fri Jun 24 10 : 59 : 56 EST 2005 WEB - INF / web . xml
123 Fri Jun 24 10 : 59 : 56 EST 2005 META - INF / maven / com . mycompany . app / my - webapp / pom . properties
52 Fri Jun 24 10 : 59 : 56 EST 2005 index . jsp
0 Fri Jun 24 10 : 59 : 56 EST 2005 WEB - INF / lib /
2713 Fri Jun 24 10 : 59 : 56 EST 2005 WEB - INF / lib / my - app - 1.0 - SNAPSHOT . jar
可见my-app-1.0-SNAPSHOT.jar
已经被放到了WEB-INF/lib
目录下。