在进行Java开发的过程当中,我接触到了Maven这套构建工具。因此,花费了点时间学习了一下这套构建工具,在学习过程当中学习到的有关Maven的知识,在这里分享给你们。html
首先,在介绍Maven这套工具以前,咱们得了解Maven是什么。
Maven,在依地语中的意思是知识的积累,Maven在最初的时候,是做为Jakarta的Turbine项目的构建工具。在Maven出现以前,不一样的Java项目使用不一样的Ant配置进行构建,而且将jar包包含在版本控制系统(CVS)中,没有一套统一的构建工具。若是有一套工具,能够拥有一套标准的方法来构建一个项目,而且能够清楚的定义一个项目是由哪些部分组成的,拥有一种简单的方法发布项目的信息,在不一样的项目之间能够分享jar包。出于这个目的,Maven被创造了出来。java
Maven最初始的目标是让开发者能够在最短的周期内能够快速的理解一个项目。为了达到这个目的,Maven解决了一下几个问题:apache
在使用Maven以前,咱们须要确保咱们已经安装了Maven构建工具。没有安装Maven构建工具的,能够参考官方提供的手册参考如何安装Mavenbash
在安装了Maven之后,能够经过命令 mvn -version
查看Maven的版本信息:app
$ mvn -version Apache Maven 3.3.3 (7994120775791599e205a5524ec3e0dfe41d4a06; 2015-04-22T19:57:37+08:00) Maven home: /usr/local/opt/maven Java version: 1.7.0_79, vendor: Oracle Corporation Java home: /Library/Java/JavaVirtualMachines/jdk1.7.0_79.jdk/Contents/Home/jre Default locale: zh_CN, platform encoding: UTF-8 OS name: "mac os x", version: "10.10.2", arch: "x86_64", family: "mac"
接下来,咱们经过Maven建立一个新的项目开始。eclipse
$ mvn -B archetype:generate \ -DarchetypeGroupId=org.apache.maven.archetypes \ -DgroupId=com.myapp \ -DartifactId=myapp
在上面的Maven命令中,咱们建立了一个名为myapp
的普通Java项目。一旦咱们执行了上面的命令,就会在当前目录下建立一个目录为myapp
的工程。在这个工程目录下,包含了一个名为pom.xml
的文件,这个新建立的pom文件内容大体以下:maven
<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.myapp</groupId> <artifactId>myapp</artifactId> <packaging>jar</packaging> <version>1.0-SNAPSHOT</version> <name>myapp</name> <url>http://maven.apache.org</url> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> </dependencies> </project>
这个pom文件表示了当前这个项目的项目对象模型(Project Object Model(POM)
。在Maven中,POM是它进行操做的基本单位。Maven的本质是以围绕POM这个概念为中心来管理整个项目的。POM中包含了项目中全部和项目相关的重要的信息,而且提供了相似一站式购物那样的依赖管理方式,能够很方便的找到当前项目关联的全部依赖来项目。ide
上面的pom.xml文件中的内容,包含了当前这个项目的相关信息。咱们首先就上面这个POM文件中的一些元素,解释下具体的含义:工具
project
这个元素是Maven的pom.xml文件的顶层元素。每一个POM文件都是以一个project
元素包裹的。modelVersion
这个元素指定了当前这个pom.xml文件使用的项目对象模型(POM)的版本。groupId
这个元素表示建立这个项目的组织的惟一标识。这个元素的值是区分一个项目的关键信息之一,它的值一般是由该项目的组织的域名的反写产生的(和Java的包名的机制同样)。artifactId
这个元素是惟一标识了该项目最终生成的artifact(能够理解为是咱们编写代码产生的一个程序,因此能够理解为是手工做品)。一个项目的artifact通常是一个jar
文件。一个项目最终生成的artifact的名字的格式是<artifactId>-<version>.<extension>
,好比上面的项目生成的artifact为myapp-1.0.jar
。packaging
这个元素指定了该artifact打包的类型(好比:jar、war、ear等)。这不仅是意味着该artifact是以什么方式打包,也指定了在构建过程当中会用到的特定的生命周期(所谓的生命周期,简单的说就是构建的过程)。packaging
元素的默认值是JAR
。version
这个元素指定了项目生成的artifact的版本号。在版本号中会包含当前项目的进度,好比这里的SNAPSHOT
。name
这个元素表示项目的名字,经常使用于生成的文档中。url
这个元素表示该项目所在的站点,经常使用于生成的文档中。description
这个元素提供了对项目的描述,一般用于生成的文档中。在项目被建立之后,除了会生成上面的pom.xml文件,还会产生一个标准的目录结构:布局
myapp |-- pom.xml `-- src |-- main | `-- java | `-- com | `-- myapp | `-- App.java `-- test `-- java `-- com `-- myapp `-- AppTest.java
上面的目录结构是Maven项目的标准布局,项目的源代码在目录${basedir}/src/main/java
目录下,而项目的测试代码存放在目录${basedir}/src/test/java
目录下。对于${basedir},这里表示的是包含了pom.xml文件的目录,也就是项目的根目录。
如今,咱们已经简单介绍了maven相关的概念和maven标准的目录结构。可是,在咱们使用Maven构建项目以前,咱们先简单了解下Maven的生命周期。
Maven的构建机制,是围绕生命周期(lifecycle)这个概念进行构建的。这意味着构建和发布一个项目的整个过程是预先被定义了的。采用这种方式进行项目构建,可让用户能够在学习不多的一部分命令的状况下经过POM对项目进行构建。
在Maven中,内建了三种构建生命周期:default
、clean
、site
。default
生命周期处理项目的部署,clean
生命周期处理项目构建后的清理工做,site
生命周期对项目的站点文档进行生成。
Maven的生命周期,又是由不一样的阶段(phase)构成的。每个生命周期,都包含了一系列的阶段,每个阶段都表示了生命周期中的一个状态。好比,对于default
生命周期来讲,包含了以下的这些阶段:
Maven在执行default
生命周期的时候,会顺序执行这些阶段来完成不一样的工做。
如今咱们已经安装好Maven,而且对Maven的相关概念有了一些认识。下面,咱们能够开始使用Maven对咱们的项目进行构建了。
在前面,咱们已经建立了一个名为myapp
的项目。如今,咱们能够经过下面的命令对这个项目进行编译。
$ mvn compile
这个命令执行之后,会有相似下方的输出:
[INFO] Scanning for projects... [INFO] [INFO] ------------------------------------------------------------------------ [INFO] Building myapp 1.0-SNAPSHOT [INFO] ------------------------------------------------------------------------ [INFO] [INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ myapp --- ... [INFO] skip non existing resourceDirectory /Users/duke/practise/myapp/src/main/resources [INFO] [INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ myapp --- [INFO] Changes detected - recompiling the module! ... [INFO] Compiling 1 source file to /Users/duke/practise/myapp/target/classes [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 1.159 s [INFO] Finished at: 2015-10-06T18:57:37+08:00 [INFO] Final Memory: 11M/156M [INFO] ------------------------------------------------------------------------
在执行这个命令之后,Maven会首先去下载全部构建当前项目所须要的插件,以及全部被当前项目所依赖全部依赖项目。从上面的输出中能够看出,咱们最终构建后的文件被输出到目录${basedir}/target/classes
中,这个目录是Maven约定的一个标准目录。使用Maven的好处之一,就是当咱们遵循Maven的约定之后,咱们可使用尽量少的配置就可让Maven为咱们构建项目。
如今,咱们已经成功地编译了咱们的项目。接下来,咱们可让Maven对单元测试进行编译和执行,经过执行下面的命令,可让Maven编译和执行咱们写的单元测试:
$ mvn test
上面的命令会有大体以下的输出:
[INFO] Scanning for projects... [INFO] [INFO] ------------------------------------------------------------------------ [INFO] Building myapp 1.0-SNAPSHOT [INFO] ------------------------------------------------------------------------ [INFO] ... [INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ myapp --- [INFO] Nothing to compile - all classes are up to date ... [INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ myapp --- [INFO] Changes detected - recompiling the module! [INFO] Compiling 1 source file to /Users/duke/practise/myapp/target/test-classes [INFO] [INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ myapp --- [INFO] Surefire report directory: /Users/duke/practise/myapp/target/surefire-reports ------------------------------------------------------- T E S T S ------------------------------------------------------- Running com.myapp.AppTest Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.004 sec Results : Tests run: 1, Failures: 0, Errors: 0, Skipped: 0 [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 1.799 s [INFO] Finished at: 2015-10-06T19:08:08+08:00 [INFO] Final Memory: 13M/156M [INFO] ------------------------------------------------------------------------
从输出中咱们能够看到,Maven在编译和执行单元测试以前,会首先编译main
中的项目代码,而后才会对test
中的单元测试进行编译和执行,并提供一个有关单元测试结果的简单报告。
在这里,咱们使用surefire
插件对单元测试进行执行。surefire
插件会对符合该插件约定的命名规则的单元测试文件进行搜索,而后进行执行。默认会执行如下命名规则的文件:
默认会排除如下命名规则的文件
固然,若是只是须要对单元测试进行编译而不须要执行,能够运行命令mvn test-comiple
实现。
如今,咱们已经对项目进行编译测试过了,咱们接下来须要对项目进行打包。当前项目,咱们在pom.xml中的packaging
元素中指定了打包的类型为jar
。因此咱们能够经过下面的命令来打jar包:
$ mvn package
执行这个命令的输出大体以下:
[INFO] Scanning for projects... [INFO] [INFO] ------------------------------------------------------------------------ [INFO] Building myapp 1.0-SNAPSHOT [INFO] ------------------------------------------------------------------------ ... [INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ myapp --- [INFO] Building jar: /Users/duke/practise/myapp/target/myapp-1.0-SNAPSHOT.jar [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 1.741 s [INFO] Finished at: 2015-10-06T19:41:05+08:00 [INFO] Final Memory: 10M/156M [INFO] ------------------------------------------------------------------------
Maven在执行这个命令的时候,会从pom.xml文件中得到打包的类型,在这个项目中为jar包类型。而后将打出来的jar输出到目录${basedir}/target
下。
在打完包之后,咱们的jar包如今仍是留在咱们的项目的target目录下,为了将这个jar部署到咱们的本地仓库(默认是~/.m2/repository
)中以供别的项目使用,咱们须要使用以下命令将当前项目的jar包部署到本地仓库中:
$ mvn install
到目前为止,咱们已经学习了怎么对项目进行打包和部署到本地仓库中了。
如今,咱们若是须要对构建除的文件进行清理,咱们须要使用以下的命令:
$ mvn clean [INFO] Scanning for projects... [INFO] [INFO] ------------------------------------------------------------------------ [INFO] Building myapp 1.0-SNAPSHOT [INFO] ------------------------------------------------------------------------ [INFO] [INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ myapp --- [INFO] Deleting /Users/duke/practise/myapp/target [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 0.255 s [INFO] Finished at: 2015-10-06T19:47:25+08:00 [INFO] Final Memory: 6M/123M [INFO] ------------------------------------------------------------------------
这个命令会删除target
目录,由于在这个目录下包含了咱们构建这个项目后输出的全部文件。如今,咱们的项目就回到被构建以前了。
咱们若是使用IDE开发环境,咱们可使用Maven生成当前项目相关的IDE的描述文件。
对于IntelliJ IEDA环境,能够用以下命令进行生成:
$ mvn idea:idea
对于eclipse环境,能够用以下的命令生成:
$ mvn eclipse:eclipse