1.什么是Maven
4.pom.xml介绍
5.Maven与myeclipse的集成使用
6.Maven项目目录结构的说明
7. Maven打包集成
=================== 正文 =================
也许你听说过Maven,也许你知道很多开源的项目里在使用它。那么什么是Maven?
简而言之,Maven是一个优秀的项目构建工具。
Maven帮助我们自动化项目构建过程,具体来说包括项目的清理,编译,测试,生成测试报告,打包和部署。只需要输入很简洁的命令,就能实现这些构建过程。比如输入mvn clean compile ,就能完成项目的清理和编译。同时,Maven提供jar包的依赖管理。
我们已经有了Ant ,它也能够完成项目构建的很多工作。那么,我们还是否需要Maven?
1) Maven更简洁,更大程度的消除了重复的步骤
Ant 是过程式的,在几乎每一个工程里,都需要在build.xml中编写 compile, pack等操作。
Maven是声明式的 , 只要在配置文件中声明项目的基本元素就可以了。编译打包等操作,只要命令行输入类似 mvn clean compile。
2) Maven提供jar包的依赖管理
某一天你接手了一个新的项目,需求既然都已明确,技术方案也已经确定,那还等啥?火速搭建框架吧。
按照惯例,你自然引入了spring。于是你从官网上找到了spring-core-3.2.3.RELEASE.jar,整合到了项目中。但是你发现启动时项目报错了,提示缺少相关类或者说依赖。以你数年码农的经验,你果断定位了问题 — 缺少了依赖的jar包,比如说spring-beans-3.2.3.RELEASE.jar。 你火速找到了这个jar包,加入了工程。再运行项目试试?你发现错误日志变了,但还是提示缺少另一个依赖。这难不倒你,你又找来了spring-aop-3.2.3.RELEASE.jar。可是再一次,启动失败了,错误日志变了,但仍然有ClassNotFound。
也许半天时间里你都在反复上面的工作 。对于各式各样的jar包和依赖,你无从下手。只能通过不断的调试,查看错误日志,再利用搜索引擎,慢慢补齐这些依赖的jar包。
Maven极大简化了这个过程,我们不再需要对各种依赖了如指掌,不再需要花费时间手工寻找,下载这些依赖。
Maven 有一个中央仓库,提供了各种第三方jar包,对于每个jar都用坐标唯一标识。我们只需要提供坐标(也就是对应一个jar),就能从中央仓库自动下载这些包及相关依赖。
比如:提供spring-core-3.2.3.RELEASE.jar的坐标,maven会自动下载这个包以及依赖包:spring-beans-3.2.3.RELEASE.jar 和 spring-aop-3.2.3.RELEASE.jar 等(这里只是例子,真实的依赖关系未必如此)。
后面我们会看到如何在中央仓库查找jar包。
下载JDK1.5或以上
下载 Maven3.0.5 http://maven.apache.org/docs/3.0.5/release-notes.html
1) Maven环境配置
解压下载的Maven,比如放在D:/soft/apache-maven-3.0.5
添加环境变量 (和配置java变量一样):
变量名: M2_HOME
变量值: D:/soft/apache-maven-3.0.5
在变量path尾部加上 ; %M2_HOME%\bin
打开命令行验证maven环境是否配置成功:
在命令行输入 mvn –v ,看是否输出Maven home等信息。
2) 本地仓库位置设置:
从中央仓库下载的jar包,都会统一存放到本地仓库中。在这里我们需要配置本地仓库的位置。
打开D:\soft\apache-maven-3.0.5\conf\setting.xml文件,在下图红框部分,填入本地仓库位置。
3) 命令行创建Maven项目
打开命令行, 输入 mvn archetype:generate
界面上会输出很多信息,并提示输入要选择的archetype编号:
这里我们直接按回车键,即选择默认编号284。输入后界面显示如下,提示选择其version:
按回车键,选择默认编号6对应的version。之后会提示输入groupId, artifactId,version,package
这里groupId指 创建项目的小组的唯一标示。 ArtifactId是 该产品id。红色框部分是我自己填写的。
后面的version和package,系统都提供了默认值。如果要采纳默认值,直接按回车键。
最后Y:处,表示是否确认以上信息,填Y按回车则开始创建。
注:
1. 如果是第一次构建项目,所有依赖的jar包都要从maven的中央仓库下载。
2. SNAPSHOT表示该版本处于开发阶段,是不稳定的版本。
至此,项目创建成功。
4) 编译Maven项目
通过命令行,进入该项目目录,输入mvn clean compile命令。
Maven会在该项目目录下新建target目录,把编译完的class文件放于其中。
此时会从中央仓库下载需要的jar包,如果需要的话。
5) 转换成eclipse项目
到目前为止,尽管Maven项目已创建,但还无法导入到eclipse(或myeclipse)中。
可以输入命令 mvn eclipse:eclipse 把该项目转换成eclipse (或myeclipse)项目。然后就可以导入了。
在5.1中,我们具体看一下如何在myeclipse中进行一些Maven构建。(之前更多的是通过命令行代码)
注:如果更新了依赖,需要执行mvn eclipse:eclipse才会更新myeclipse 中build path。否则myeclipse中的libraries不会引入新的依赖。
在之前创建的Maven项目中,我们发现根目录下有一个pom.xml文件。它是Maven项目的标志。我们看一下pom文件的内容。
groupId : 创建项目的小组的唯一标示。
artifactId: 该产品id。会作为产生的jar/war包名的一部分。它和version一起构成输出包的包名。
Version: 产品版本
Packaging: 打包的类型
Name: 项目名称,用于maven产生的文档中。
url:指定项目站点,通常用于maven产生的文档中。
description:描述此项目,通常用于maven产生的文档中。
Properties: 属性。这里设置编码方式为UTF-8
Dependencies: 依赖的jar包
我们注意到,在dependency中,也有<groupId>,<artifactId>,<version>这样的节点。这三个元素是jar包坐标的重要组成部分。它指定了我们要从中央仓库获取的jar。
那么如何知道所要jar的坐标呢?
可以在Maven搜索站中搜索: http://search.maven.org/
在搜索结果中找到需要的jar包,把相应的坐标填写在pom.xml文件中。
此外,我们还注意到,<dependency>下有一个<scope>test</scope>。它设定了jar包的作用域,这里指junit包仅在测试时使用。在正式打包的时候,并不会引入到工程中。如果去掉这行代码,那么Maven会采用默认的compile范围,那么无论在测试或者打包时,该jar包都会被工程引用,生成的包中会含有junit。
5.1 在myeclipse中的项目构建
在具体操作之前,先做2个基础设置:
1)设置Maven配置位置,取消myeclipse内嵌的Maven (Embedded Maven)
点击Window -> Preference -> MyEclipse Enterprise Workbench -> Maven4Myeclipse
在红色框处填写Maven配置文件位置。
再点击Maven4Myeclipse 下的Installation , 取消右边框中的Embedded Maven, 增加一个外部Maven,指向Maven安装目录
内嵌的Maven版本可能会与我们之前实际安装的外部Maven版本不一致,导致一些异常错误,因此不使用。
2)新建一个指向Maven本地仓库的Classpath变量
点击Window -> Preference -> Java –> Build Path -> ClassPath Variable ,然后点add,新增一个
变量M2_REPO, 指向Maven本地仓库。
然后看一下如何进行编译,测试等构建操作。
右键pom.xml -> run as, 在弹出框中我们看到:
Maven package
Maven clean
Maven test
….
他们依次相当于命令行的:
mvn package(打包)
mvn clean (清理)
mvn test (执行测试用例)
注: 每次打包时都会自动执行一遍测试用例,生成测试报告。
5.2 直接在myeclipse中的创建Maven项目
点击 File -> new , 选择Java Maven Project ,然后弹出对话框:
其中Group Id 和 Artifact Id应该不陌生了,同命令行创建是一样的。
创建完,就可以看到pom.xml文件生成了。并且工程上有一个红色的Maven标志。
这里特别说明一下:
如果此时需要增加依赖,可以修改pom.xml。修改完之后,系统会立即更新classpath,可以在工程的libraries中看到新加的依赖已经加入了。
但是如果通过第三节命令行的方式创建的工程,那么修改完pom.xml之后,myeclipse中的classpath并不会立即更新,需要执行mvn eclipse:eclipse。(注意执行该命令之后,工程的class文件输出路径会恢复默认值)
6.1 默认目录结构
Maven项目遵循统一的目录结构规范。在构建过程中,Maven会根据默认的路径去寻找相关的代码。新的工程应尽可能的遵循这种结构
1) 普通Java工程
无论以何种方式创建完Maven Java工程(命令行或者IDE),最终呈现的目录结构都是:
其中src/test目录下的都是测试用的代码和配置文件,打包时不会引入这些文件。
而src/main下都是项目的主代码。
2) Java Web 工程
注意与传统java web 项目不同, webapp目录被放置于 src/main/ 目录下。由于部署时会从设置的web根目录找文件,因此必须确保:
1) web-root folder的值为 src/main/webapp
2) class输出路径的值为 src/main/webapp/WEB-INF/classes
6.2 自定义目录结构
如果要把已有项目迁移成Maven项目,目录结构可能不合适进行改造。这时就需要通过配置pom.xml文件,来修改Maven的各种路径,包括主代码路径,测试代码路径等。以下是一些可配的路径:
1) 主源码路径
<project>
<build>
<sourceDirectory> XXX </ sourceDirectory>
</build>
</project>
在这里简写成 project.build.sourceDirectory
2) 测试源码路径
Project.build.testDirectory
其他还有构建项目输出目录,项目主代码编译输出目录等。有兴趣可以参见《Maven实战》
通常情况下,Maven只是把普通Java 工程打成jar包。 但是很多时候,我们实际需要的可能是一个更复杂的目录结构。生成的不仅包含jar包,还包括lib,configure,shell等目录。
7.1 场景
有这样一个工程test,目录结构如下:
想把该工程打成一个zip包,zip包中包含一个根目录,根目录下的目录结构是:
2.如何实现
为达到这个效果,我们需要做两件事:
1.先修改pom.xml,引入该插件。
2.再增加一个配置文件打包配置文件package.xml。
我们看一下的配置文件大体是怎么样的:
Pom.xml中增加:
artifactId 指出了要用的插件产品Id
configuration 中 appendAssemblyId 代表是否在输出的包名中添加集成编号,这里false表示不需要。
Descriptors 表示具体描述打包的配置文件是哪个。
execution的设置是为了将maven-assembly-plugin继承到标准的maven打包过程中,这样在运行maven-package时就会执行maven-assembly-plugin的操作,从而实现我们需要的自定义打包。
Package.xml的内容如下:
format : 打包格式,这里是zip
fileSet:里面设置了源地址和目标目录。比如第一个fileSet,把src/main/resources下的文件打包到config目录下。
Dependency: 处理依赖包的打包位置。其中useProjectArtifact表示包含项目本身生成的jar包(为true时包含)。Include表示打包时,需要包含的依赖。通常用groupId:artifactId的形式指定要加入哪些依赖。
注:source package中有一个叫major,这里并没有配置把它下面的内容打包,因此输出包内没有major下的类。
Package.xml 可供设置的内容很多,详情请参考:
http://maven.apache.org/plugins/maven-assembly-plugin/assembly.html