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概述
一个基本的Pom文件
4.0.0 com.mycompany.app my-app jar 1.0-SNAPSHOT Maven Quick Start Archetype http://maven.apache.org junit junit 4.11 test
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中增加如下内容:
org.apache.maven.plugins maven-compiler-plugin 3.3
<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.propertiesapplication.name=${project.name}application.version=${project.version}
那么需要在pom文件中做如下的定义:
4.0.0 com.mycompany.app my-app 1.0-SNAPSHOT jar Maven Quick Start Archetype http://maven.apache.org junit junit 4.11 test src/main/resources true
执行mvn process-resources
命令后,在target/classes
下找到application.properties
可以看到如下结果:
# application.propertiesapplication.name=Maven Quick Start Archetypeapplication.version=1.0-SNAPSHOT
可见其中形如${<property name>}
的变量已经被替换成了对应的值,如果要引入其它文件中定义的属性,只需要在pom文件中定义<filters>
,比如:
src/main/filters/filter.properties src/main/resources true
那么Maven会先读出filter.properties
中的属性,然后把这些属性注入对应的resources中。
Dependencies
<dependencies>
标签下列出了所有的外部依赖,比如下面的Pom文件添加了Junit的依赖:
4.0.0 com.mycompany.app my-app 1.0-SNAPSHOT jar Maven Quick Start Archetype http://maven.apache.org junit junit 4.11 test
<dependency>
的<scope>
标签的值可以为compile,test和runtime,当Maven编译项目时,它首先会在${user.home}/.m2/repository
这个本地库目录下寻找所需的依赖,如果没有会去远程的库上寻找,并将其下载到本地库中,默认的远程库地址为http://repo.maven.apache.org/maven2/
。
包的发布
当需要发布一个包的远程仓库时,需要配置库的地址和相应的权限,一个范例如下:
4.0.0 com.mycompany.app my-app 1.0-SNAPSHOT jar Maven Quick Start Archetype http://maven.apache.org junit junit 4.11 test org.apache.codehaus.plexus plexus-utils 1.0.4 src/main/filters/filters.properties src/main/resources true mycompany-repository MyCompany Repository scp://repository.mycompany.com/repository/maven2
它所需要的权限配置在settings.xml
中:
... ... mycompany-repository jvanzyl /path/to/identity (default is ~/.ssh/id_dsa)my_key_passphrase
多Modules管理
Maven很好的支持了多个Modules的管理,假如一个Maven项目结构如下:
+- pom.xml+- my-app| +- pom.xml| +- src| +- main| +- java+- my-webapp| +- pom.xml| +- src| +- main| +- webapp
对于根目录下的pom文件,内容如下:
4.0.0 com.mycompany.app app 1.0-SNAPSHOT pom my-app my-webapp
其中的<modules>
定义了其管理的两个子modules。
假如my-webapp需要依赖my-app包,那么在my-webapp/pom.xml
中增加:
...... com.mycompany.app my-app 1.0-SNAPSHOT
然后在my-app和my-webapp的pom文件中都增加parent配置:
... com.mycompany.app app 1.0-SNAPSHOT
然后在最顶层目录下执行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
目录下。