Maven是一个异常强大的构建工具,可以帮咱们自动化构建过程,从清理、编译、测试到生成报告,再到打包和部署。经过Maven,咱们只须要输入简单的命令(如mvn clean install),就会帮咱们处理繁琐的任务。Maven最大化的消除了构建的重复,抽象了构建生命周期,而且为绝大部分的构建任务提供了已实现的插件。好比说测试,咱们只须要遵循Maven的约定编写好测试用例,当咱们运行构建的时候,这些测试便会自动运行。除此以外,Maven能帮助咱们标准化构建过程。在Maven以前,十个项目可能有十种构建方式,但经过Maven,全部项目的构建命令都是简单一致的。有利于促进项目团队的标准化。java
Maven是笔者接触的第一个脱离于IDE的命令行构建工具,笔者以前一直是基于Visual Studio下进行Windows驱动开发,并非很能明白Builder与IDE之间的区别。依赖大量的手工操做。编译、测试、代码生成等工做都是相互独立的,很难一键完成全部工做。手工劳动每每意味着低效,意味着容易出错。很难在项目中统一全部的IDE配置,每一个人都有本身的喜爱。也正是因为这个缘由,一个在机器A上能够成功运行的任务,到了机器B的IDE中可能就会失败。linux
Make将本身和操做系统绑定在一块儿了。也就是说,使用Make,就不能实现(至少很难)跨平台的构建,这对于Java来讲是很是不友好的。此外,Makefile的语法也成问题,不少人抱怨Make构建失败的缘由每每是一个难以发现的空格或Tab使用错误。git
和Make同样,Ant也都是过程式的,开发者显式地指定每个目标,以及完成该目标所须要执行的任务。针对每个项目,开发者都须要从新编写这一过程,这里其实隐含着很大的重复。Maven是声明式的,项目构建过程和过程各个阶段所需的工做都由插件实现,而且大部分插件都是现成的,开发者只须要声明项目的基本元素,Maven就执行内置的、完整的构建过程。这在很大程度上消除了重复。github
Ant是没有依赖管理的,因此很长一段时间Ant用户都不得不手工管理依赖,这是一个使人头疼的问题。幸运的是,Ant用户如今能够借助Ivy管理依赖。而对于Maven用户来讲,依赖管理是理所固然的,Maven不只内置了依赖管理,更有一个可能拥有全世界最多Java开源软件包的中央仓库,Maven用户无须进行任何配置就能够直接享用。web
可从apache官方下载最新的Maven 压缩包,解压便可。而后设置下系统的环境变量。以下所示:apache
M2HOME:maven安装目录服务器
Path:追加maven安装目录下的bin目录网络
在用户目录下,咱们能够发现.m2文件夹。默认状况下,该文件夹下放置了Maven本地仓库.m2/repository。全部的Maven构件(artifact)都被存储到该仓库中,以方便重用。默认状况下,~/.m2目录下除了repository仓库以外就没有其余目录和文件了,不过大多数Maven用户须要复制M2HOME/conf/settings.xml文件到~/.m2/settings.xmlapp
本节列举出部分经常使用的Maven命令:dom
mvn -v 查看maven版本
mvn compile 编译
mvn test 测试
mvn package 打包
mvn clean 删除target
mvn install 安装jar包到本地仓库中
建立一个新工程
mvn archetype:generate -DgroupId=co.hoteam -DartifactId=Zigbee -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
就像Make的Makefile,Ant的build.xml同样,Maven项目的核心是pom.xml。
首先建立一个名为hello-world的文件夹,打开该文件夹,新建一个名为pom.xml的文件,输入其内容以下:
<?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> <groupId>com.juvenxu.mvnbook</groupId> <artifactId>hello-world</artifactId> <version>1.0-SNAPSHOT</version> <name>Maven Hello World Project</name> </project>
代码的第一行是XML头,指定了该xml文档的版本和编码方式。紧接着是project元素,project是全部pom.xml的根元素,它还声明了一些POM相关的命名空间及xsd元素,虽然这些属性不是必须的,但使用这些属性可以让第三方工具(如IDE中的XML编辑器)帮助咱们快速编辑POM。
根元素下的第一个子元素modelVersion指定了当前POM模型的版本,对于Maven2及Maven 3来讲,它只能是4.0.0。这段代码中最重要的是groupId,artifactId和version三行。这三个元素定义了一个项目基本的坐标,在Maven的世界,任何的jar、pom或者war都是以基于这些基本的坐标进行区分的。
groupId定义了项目属于哪一个组,这个组每每和项目所在的组织或公司存在关联,譬如你在googlecode上创建了一个名为myapp的项目,那么groupId就应该是com.googlecode.myapp,若是你的公司是mycom,有一个项目为myapp,那么groupId就应该是com.mycom.myapp。本书中全部的代码都基于groupId com.juvenxu.mvnbook。
artifactId定义了当前Maven项目在组中惟一的ID,咱们为这个Hello World项目定义artifactId为hello-world,本书其余章节代码会被分配其余的artifactId。而在前面的groupId为com.googlecode.myapp的例子中,你可能会为不一样的子项目(模块)分配artifactId,如:myapp-util、myapp-domain、myapp-web等等。
version指定了Hello World项目当前的版本——1.0-SNAPSHOT。SNAPSHOT意为快照,说明该项目还处于开发中,是不稳定的版本。随着项目的发展,version会不断更新,如升级为1.0、1.1-SNAPSHOT、1.一、2.0等等。
最后一个name元素声明了一个对于用户更为友好的项目名称,虽然这不是必须的,但我仍是推荐为每一个POM声明name,以方便信息交流。 没有任何实际的Java代码,咱们就可以定义一个Maven项目的POM,这体现了Maven的一大优势,它能让项目对象模型最大程度地与实际代码相独立,咱们能够称之为解耦,或者正交性,这在很大程度上避免了Java代码和POM代码的相互影响。好比当项目须要升级版本时,只须要修改POM,而不须要更改Java代码;而在POM稳定以后,平常的Java代码开发工做基本不涉及POM的修改。
项目主代码和测试代码不一样,项目的主代码会被打包到最终的构件中(好比jar),而测试代码只在运行测试时用到,不会被打包。默认状况下,Maven假设项目主代码位于src/main/java目录,咱们遵循Maven的约定,建立该目录,而后在该目录下建立文件com/juvenxu/mvnbook/helloworld/HelloWorld.java,其内容以下:
package com.juvenxu.mvnbook.helloworld; public class HelloWorld { public String sayHello() { return "Hello Maven"; } public static void main(String[] args) { System.out.print( new HelloWorld().sayHello() ); } }
关于该Java代码有两点须要注意。首先,在95%以上的状况下,咱们应该把项目主代码放到src/main/java/目录下(遵循Maven的约定),而无须额外的配置,Maven会自动搜寻该目录找到项目主代码。其次,该Java类的包名是com.juvenxu.mvnbook.helloworld,这与咱们以前在POM中定义的groupId和artifactId相吻合。通常来讲,项目中Java类的包都应该基于项目的groupId和artifactId,这样更加清晰,更加符合逻辑,也方便搜索构件或者Java类。 代码编写完毕后,咱们使用Maven进行编译,在项目根目录下运行命令 mvn clean compile 便可。
clean告诉Maven清理输出目录target/,compile告诉Maven编译项目主代码,从输出中咱们看到Maven首先执行了clean:clean任务,删除target/目录,默认状况下Maven构建的全部输出都在target/目录中;接着执行resources:resources任务(未定义项目资源,暂且略过);最后执行compiler:compile任务,将项目主代码编译至target/classes目录(编译好的类为com/juvenxu/mvnbook/helloworld/HelloWorld.Class)。
编辑~/.m2/settings.xml文件(若是没有该文件,则复制$M2HOME/conf/settings.xml)。添加代理配置以下:
<settings> ... <pqroxies> <proxy> <id>my-proxy</id> <active>true</active> <protocol>http</protocol> <host>代理服务器主机名</host> <port>端口号</port> <!-- <username>***</username> <password>***</password> <nonProxyHosts>repository.mycom.com|*.google.com</nonProxyHosts> --> </proxy> </proxies> ... </settings>
众所周知的缘由,国内有时候并不可以很顺畅的访问Maven的中央仓库,每每咱们须要访问国内的镜像地址:
OSChina Maven教程
<mirror> <id>CN</id> <name>OSChina Central</name> <url>http://maven.oschina.net/content/groups/public/</url> <mirrorOf>central</mirrorOf> </mirror>
(1)有时候由于众所周知的网络问题,致使Maven没法访问中央仓库而后扔出一大堆错误,这个时候能够尝试参考上文中的设置代理。可是也要注意,是否是有一些私库中的Repository。
(1)有时候执行mvn compile
时候会爆出没法找到junit的错误,可能的解决方法有:
在Eclipse的Projects选项中使用Projects Clean
在pom.xml中引入junit依赖项,而且保证其scope为compile:
<dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency>
(2)有时候在Eclipse下执行mvn compile
或者相关命令时,会报某某文件出现不识别字符或者非UTF-8编码,此时能够作几步检查:
检查对应的Java文件是否有Bom头
检查对应的Java文件的编码
若是都没有问题,在Eclipse中先将文件编码设置为GBK,再改回UTF-8试试。