1、Maven高级(详解)高级(详解)1 10 01 10 0传统开发回顾 收集依赖构件到CLASSPATH 编写源代码、配置信息 Javac编译 单元测试 产品打包、发行 代码共享、储存,以及版本控制经常遇到哪些问题?严重依赖IDE?1 10 01 10 0主要内容Maven介绍、安装、常用命令Eclipse下Maven项目开发坐标与依赖多模型开发常用插件和自动化部署内部仓库使用生成站点Maven高级主题 1 10 01 10 0Maven介绍 Maven是一个项目管理工具,它包含了一项目对象模型(Project Object Model),一组标准集合,一个项目生命周期(Project Lif
2、ecycle),一个依赖管理系统(Dependency Manangement System),和用来运行定义在生命周期阶段中插件目标的逻辑。Maven是面向技术层面,针对Java开发项目管理工具,它提供了构建工具所提供功能的超集,除了构建功能之外,Maven还可以管理项目结构、管理依赖关系、生成报告、生成Web站点、有助于团队成员之间的交流与协作。1 10 01 10 0 指导开发:提供了Java项目的最佳开发实践,自由开发项目骨架而可自动生成项目结构。自动编译:不仅仅只像Ant自动编译,还包括测试,打包,发布,文档生成,项目站点生成 依赖管理:Maven可以方便地管理应用程序依赖,例如第三
3、方依赖、模型依赖 无限扩展:插件模式可以无限增强Maven功能,例如通过Tomcat、Jetty插件可以自由控制其服务器。持续集成:鼓励开发者积极提交代码,更早地发现程序错误,在并行开发中稳妥推进。开发协作:更简单和谐的团队协作 开发者通过开发者通过Maven管理项目从中受益管理项目从中受益:Maven监管项目生命周期几个重要的过程:几个重要的过程:compile:编译test:测试package:打包install:安装deploy:发布 1 10 01 10 0Maven版本 Maven2完成了对Maven1的重写。重写的首要目的是要提供了强大的Java构建和包含API的项目,允许Mave
4、n被植入任何地方,尤其是高级别的产品如IDEs、质量工具、报告工具等这些。Maven2构建生命周期的概念正式化,其比Maven更易扩展;Maven3在2.x基础上大幅提升性能。可以自动指定父版本,并行生成,更好的完整性报告、多语言生成、更好地支持M2Eclipse 我们要使用Maven3 1 10 01 10 0Maven安装 下载安装包 地址:http:/maven.apache.org/download.html 当前版本为3.0 Windows系统下安装:首先需要确认系统中装有JDK(版本1.4+);将压缩包解压到本地磁盘某目录中,该目录则称为安装目录。例如 D:opensourceap
5、ache-maven-3.0目录结构:bin Maven的运行脚本boot Maven自己的类装载器conf 该目录下包含了全局行为定制文件setting.xmllib Maven运行时所需的类库.1 10 01 10 0Maven安装 配置环境变量M2_HOME=安装目录在path变量中增加%M2_HOME%binMAVEN_OPTS=-Xms NNNm Xmx NNNm(非必要项,可防止内存溢出。其中NNN表示具体的内存数量)检查安装正确性在命令行提示符下执行:mvn v能看到Maven和JDK的版本号为安装正确 小试Maven命令mvn help:system该命令将会下载help插件并
6、运行它,且打印出Java系统属性和环境变量 1 10 01 10 0Maven名词解释Project:任何您想build的事物,Maven都可以认为它们是工程。这些工程被定义为工程对象模型(POM,Poject Object Model)。一个工程可以依赖其它的工程;一个工程也可以由多个子工程构成。POM:POM(pom.xml)是Maven的核心文件,它是指示Maven如何工作的元数据文件,类似于Ant中的build.xml文件。POM文件位于每个工程的根目录中。GroupId:groupId是一个工程的在全局中唯一的标识符,一般地,它就是工程名。groupId有利于使用一个完全的包名,将一
7、个工程从其它有类似名称的工程里区别出来。Artifact:artifact 是工程将要产生或需要使用的文件,它可以是jar文件,源文件,二进制文件,war文件,甚至是pom文件。每个artifact都由groupId和 artifactId组合的标识符唯一识别。需要被使用(依赖)的artifact都要放在仓库(见Repository)中,否则Maven无法找到(识别)它们。Dependency:为了能够build或运行,一个典型的Java工程会依赖其它的包。在Maven中,这些被依赖的包就被称为dependency。dependency一般是其它工程的artifact。Plug-in:Mave
8、n是由插件组织的,它的每一个功能都是由插件提供的。插件提供goal(类似于Ant中的target),并根据在POM中找到的元数据去完成工作。主要的Maven插件要是由Java写成的,但它也支持用Beanshell或Ant脚本写成的插件。Repository:仓库。1 10 01 10 0setting.xml$user.home/.m2/settings.xml为用户范围的配置文件$M2_HOME/conf/settings.xml为全局范围的配置文件,修改后将影响本机所有用户的配置建议:只修改用户级别的配置,既不影响其它用户,也不影响后期升级。配置介绍localRepository:自定义本
9、地库路径,默认在$user.home/.m2中interactiveMode:offline:是否每次编译都去查找远程中心库pluginGroups:插件组,例如org.mortbay.jettyproxies:通过代理访问外部库servers:集成认证服务,例如集成Tomcatmirrors:镜像库,可以指定内部中心库profiles:个性配置,需要在Activation标签中激活activeProfiles:表示激活的profile 1 10 01 10 0Maven仓库 远程公用仓库Maven内置了远程公用仓库:http:/repo1.maven.org/maven2这个公共仓库是由Ma
10、ven自己维护,里面有大量的常用类库,并包含了世界上大部分流行的开源项目构件。目前是以java为主。内部中心仓库也称私有共享仓库(私服)。一般是由公司自己设立的,只为本公司内部共享使用。它既可以作为公司内部构件协作和存档,也可作为公用类库镜像缓存,减少在外部访问和下载的频率。Nexus和Artifactory均可搭建仓库服务器。但后者支持LDAP认证,这样就可以将私有仓库的认证集成到公司已经有的LDAP认证服务器。内部中心库又可以连接第三方库,例如Jboss中心库、Spring中心库,以随时获得最新版本的第三方构件。1 10 01 10 0Maven仓库 本地仓库Maven会将工程中依赖的构件
11、(Jar包)从远程下载到本机一个目录下管理,通常默认在$user.home/.m2/repository下。自Maven2以后,构件的存储方式通常是groupId/artifactId/version/*.jar修改本地库位置:在$M2_HOME/conf/setting.xml文件的元素中指定路径,例如:D:/my_repository指定五八同城公司内部中心库:1 10 01 10 0Maven常用命令常用命令检测Maven、JDK版本mvn v 或者 mvn-version获取帮助选项mvn h 或者 mvn help显示详细错误信息mvn e创建Java项目mvn archetype:
12、create -DgroupId=$groupId -DartifactId=$artifactId示例:mvn archetype:create -DgroupId=com.howsun -DartifactId=myApp -Dversion=0.1创建Web项目 mvn archetype:create -DgroupId=$packageName -DartifactId=$webappName -DarchetypeArtifactId=maven-archetype-webapp创建其它项目(例如SSH、JPA、JSF、Seam)mvn archetype:generate 然后根
13、据提示选择项目骨架、groupid、artifactid、版本号 Maven3已有上百个项目骨架转换成Eclipse工程mvn eclipse:eclipsemvn eclipse:clean /清除Eclipse设置信息转换成idea项目:mvn idea:idea编译mvn compile编译测试代码mvn test-compile产生Site:mvn site测试mvn test /运行测试mvn test-Dtest=$类名/单独运行测试类清除mvn clean /将清除原来编译的结果打包mvn packagemvn package Dmaven.test.skip=true/打包时不
14、执行测试发布mvn install/将项目打包成构件安装到本地仓库mvn deploy /发布到本地仓库或服务器(例如Tomcat、Jboss)手动添加构件到仓库mvn install:install-file-Dfile=$jar包文件位置-DgroupId=$groupId-DartifactId=$artifactId-Dversion=$版本号-Dpackaging=jar-DgeneratePom=$是否同时创建pom文件复制依赖构件到相应目录mvn dependency:copy-dependencies-DoutputDirectory=$目标目录-DexcludeScope=$
15、scope-Dsilent=true示例:mvn dependency:copy-dependencies -DoutputDirectory=WebRoot/WEB-INF/lib -Dsilent=true -DincludeScope=runtime 显示一个插件的详细信息(configuration,goals等):mvn help:describe-Dplugin=pluginName-Ddetail 1 10 01 10 0pom.xml是Maven项目的核心配置文件,位于每个工程的根目录,指示Maven工作的元数据文件。节点介绍 :文件的根节点.:pom.xml使用的对象模型版本
16、.:创建项目的组织或团体的唯一 Id.:项目的唯一 Id,可视为项目名.:打包类型,一般有JAR,WAR,EAR 等 :产品的版本号.:项目的显示名,常用于 Maven 生成的文档。:组织的站点,常用于 Maven 生成的文档。:项目描述,常用于 Maven 生成的文档。1 10 01 10 0pom.xml:构件依赖:模型继承:依赖管理:创建报告:构建:引用第三方仓库:许可 1 10 01 10 0POM全景图 1 10 01 10 0Eclipse中使用中使用Maven 为Eclipse提供JDK支持Eclipse是运行在JRE之上,但Maven需要JDK的一些支持,需要指定JDK,在Ec
17、lipse安装目录中的eclipse.ini文件中增加:-vm$%JAVA_HOME%binjavaw.exe 安装M2Eclipse插件 Help-InstallNewSoftware-Work with-Add核心组件:Name:m2eLocation:http:/m2eclipse.sonatype.org/sites/m2e扩展组件:Name:m2e-extrasLocation:http:/m2eclipse.sonatype.org/sites/m2e-extras 1 10 01 10 0M2Eclipse扩展组件介绍Maven SCM handler for Subclipse
18、:该组件能帮助我们直接从Subversion服务器签出Maven项目(须先安装Subclipse)Maven SCM handler for Team/CVS:该组件能帮助我们直接从CVS服务器签出Maven项目Maven SCM Integration:Eclipse环境中Maven与SCM集成核心的模块Maven issue tracking configurator for Mylyn:帮助我们使用POM中的缺陷跟踪系统信息连接Mylyn至服务器Maven Integration for WTP:WTP是Eclipse的Web工具平台,可以很方便地编辑JSP、HTML、Javascrip
19、t、CSS。该模块可以让Eclipse自动读取POM信息并配置WTP项目M2eclipse Extensions Development Support:用来支持扩展m2eclipseProject Configurators for commonly used maven plugins:一个临时的组件,用来支持一些Maven插件与Eclipse的集成。红色的建议安装,安装之前需要确认Eclipse已经安装了其主插件,见下页 1 10 01 10 0Eclipse常用插件安装Mylyn/集成任务管理和上下文管理Name:Mylyn for Eclipse 3.4 and 3.5Locatio
20、n:http:/download.eclipse.org/tools/mylyn/update/e3.4/aspectJ/切面编程插件Name:aspectJ Location:http:/download.eclipse.org/tools/ajdt/35/updateSubclipse /SVN版本控制器客户端Name:Subclipse 1.6.x Update Site Location:http:/subclipse.tigris.org/update_1.6.xWTP /Web 工具平台Name:The Eclipse Web Tools Platform(WTP)Project
21、update site Location:http:/download.eclipse.org/webtools/updatesEPP/负责创建Eclipse下载软件包Name:EPP Packages Repository Location:http:/download.eclipse.org/technology/epp/packages/galileo 1 10 01 10 0替换Eclipse内置的Maven 强烈建议统一本地Maven程序 Window-Perferences-Maven-Installations-Add 指定到M2_HOME目录 1 10 01 10 0在Ecli
22、pse中创建Maven项目 File-new-other-Maven-Maven Object Next 勾上Create a simple project这样可以跳过项目骨架选择 Next 填写GroupId和Artifact Id Finish 1 10 01 10 0在Eclipse中创建Maven项目 完成后的工程示例见右图 做好工程准备工作:修改项目的编码为UTF-8 修改编译级别在1.5+指定自己的JRE系统库 1 10 01 10 0在Eclipse中导入Maven项目 File-Import-Maven-Existing Maven Projects-Next-指定路径 也可以
23、将非Eclipse工程转换成该标准工程进入项目,即pom.xml当前目录,执行命令:mvn eclipse:eclipse 然后在Eclipse中:File-Import-General-Existing Projects into Workspace-Next 指定路径 将Projects出现的项目勾上并点击完成 1 10 01 10 0坐标 一个Java构件的五大坐标元素:groupId:组IDartifactId:实际项目的IDversion:版本package:包类型,如JAR、EAR、POMclassifier:分类,如二进制包,源、文档通过这种规则就可以定位到世界上任何一个构件 1
24、 10 01 10 0 1 10 01 10 0依赖 依赖配置 1 10 01 10 0依赖配置详细介绍 groupId、artifactId、version是依赖的基本坐标,缺一不可,其它两个坐标元素不指定时将采用默认值 type:依赖的类型,对应坐标packaging,默认为jar optional:标记依赖是否可选A-B-C,那么当A依赖于C时就可以设为可选。exclusions:排除传递依赖 1 10 01 10 0依赖配置详细介绍 scope:依赖范围p compile:编译范围,默认scope,在classpath中存在p provided:已提供范围,比如容器提供Servlet
25、APIp runtime:运行时范围,编译不需要,接口与实现分离p test:测试范围,单元测试环境需要p system:系统范围,自定义构件,指定systemPathp import:导入依赖 1 10 01 10 0依赖范围与ClassPath关系依赖范围依赖范围对于编译对于编译classpath有效有效对于测试对于测试classpath有效有效对于运行时对于运行时classpath有效有效例子例子compileYYYspring-coretest-Y-JunitprovidedYY-servlet-apiruntime-YYJDBC驱动systemYY-本地的,Maven仓库之外的类库i
26、mport导入依赖不会对表中三种classpath起作用 1 10 01 10 0传递性依赖MyProjectWFSpring传递依赖关系表 1 10 01 10 0依赖调解uA-B-C-D-X(1.6)uA-D-X(2.0)X是A的传递依赖 调解原则:第一原则:路径近者优先原则x2.0传递给A最近第二原则:第一声明者优先原则当路径相等时,则由POM声明的依赖顺序决定 1 10 01 10 0依赖优化 排除依赖 归类依赖UTF-83.0.5.RELEASE1.6.1在后面的依赖中只需指明version的引用$org.slf4j.version 优化依赖mvn dependency:list /
27、打印出依赖列表mvn dependency:tree /打印出依赖树mvn dependency:analyze/分析当前依赖通过这些工具进行分析后适当优化 1 10 01 10 0多模型开发:继承通过子项目来继承,可以共享父项目定义的所有的值。比如自定义构建信息,版本仲裁。特点:1.单亲父节点2.从叶节点往上定义的3.允许覆盖.1 10 01 10 0多模型开发:组合 组合:定义一组构建模块的聚集 特点:1.组合可以独立于继承 2.上层节点进行组合定义myproject-allmyproject-daomyproject-bizmyproject-mvc 1 10 01 10 0在POM中使
28、用第三方仓库例如:org.hibernatehttp:/repository.jboss.org/maven2maven2-J Repository for Maven 2https:/maven2- 1 10 01 10 0构建配置最终名 PS:一般构建时加上必要的插件就可以,不需要更多的配置,因为它有内部约定。如果需要改变配置,例如源代码文件夹、编译打包结果文件夹等等,都是可以改变的。1 10 01 10 0常用插件 Maven编译插件org.apache.maven.pluginsmaven-compiler-plugin1.61.6UTF-8命令:mvn compilePS:该插件是默
29、认插件,如果没有配置,Maven将以1.3级别来编译 1 10 01 10 0JAR包生成插件org.apache.maven.pluginsmaven-jar-plugin org.sonatype.mavenbook.weather.Maintrue命令:mvn jar:jarPS:默认插件,如果需要更多的配置(例如jar档案说明信息、选择性打包等等),可以查看官方文档http:/maven.apache.org/plugins/maven-jar-plugin/1 10 01 10 0 测试插件org.apache.maven.pluginsmaven-surefire-plugintr
30、ue作用:可以跳过测试当测试失败仍然执行PS:默认插件,也可以命令后面加上参数来替代配置:-Dmaven.test.skip=true 1 10 01 10 0 Tomcat插件org.codehaus.mojotomcat-maven-plugin命令:mvn tomcat:run 1 10 01 10 0Tomcat插件常用配置 /8080 UTF-8/uri编码PS:这些配置适合在Eclipse中通过Maven启动Tomcat来测试自己的Web项目,如果要完全控制Tomcat,并自动将项目发布到Tomcat中,则还需要添加标签,并在setting.xml中添加Tomcat管理员账号,详情
31、见官方说明:http:/mojo.codehaus.org/tomcat-maven-plugin/1 10 01 10 0Jetty插件org.mortbay.jettyjetty-maven-plugin08060000/插件命令:mvn jetty:run 1 10 01 10 0自动化部署CARGO 自动化部署利器,使Maven如虎添翼自动化部署:非官方插件,它可以向Tomcat、Jetty、Resin、JBoss、Glassfish、WebLogic等容器中部署项目。功能非常强大官方网址:http:/cargo.codehaus.org/以自动化部署到Tomcat为例:见下页 1 1
32、0 01 10 0自动化部署Tomcat向远程Tomcat部署Web项目 org.codehaus.cargo cargo-maven2-plugin tomcat6x remote runtime Tomcat账号 密码 http:/localhost/manager 命令:cargo:deploy 1 10 01 10 0自动化部署嵌入式Tomcat嵌入式Tomcat部署Web项目:将Tomcat中间件嵌入到自己的Web工程中。org.codehaus.cargo cargo-maven2-plugin tomcat6x$CATALINA_HOME standalone$project.b
33、uild.directory/tomcat6x 命令:cargo:start 1 10 01 10 0Maven插件总结Maven一切行为都是居于插件完成的artifactId以xxx-maven-plugin形式的是Maven官方插件,一般可以默认使用(不需要配置)Apache提供的Maven插件列表:http:/maven.apache.org/plugins/index.htmlCodehaus提供的Maven插件列表:http:/mojo.codehaus.org/plugins.html可以开发自己的插件项目,使得Maven功能无限扩展 1 10 01 10 0公司内部仓库使用内部仓
34、库搭建:推荐Nexus作内部仓库服务器,有关Nexus获取和安装,请见官方网站:http:/nexus.sonatype.org/界面 1 10 01 10 0公司内部仓库使用(续)在setting.xml中添加nexus服务器账号。如何在Nexus服务器创建账号请参考官方说明 releases 用户名 密码 Snapshots 用户名 密码 1 10 01 10 0公司内部仓库使用(续)将项目发行到公司内部仓库。在pom.xml中添加:releases Internal Releases releases仓库地址 Snapshots Internal Snapshots snapshots仓
35、库地址 命令:mvn deploy 1 10 01 10 0公司内部仓库使用(续)将内部仓库设成镜像仓库:内部仓库并非远程中心仓库,然后用它来镜像远程仓库,能大大加快下载效率,降低远程的仓库中心的负载 nexus *内部公共仓库地址 nexus-public-snapshots public-snapshots 内部快照仓库地址 1 10 01 10 0公司内部仓库使用(续)将远程仓库地址覆盖到公司内部(镜像)仓库:development central http:/central true true central http:/central true true public-snapsho
36、ts public-snapshots http:/public-snapshots false true public-snapshots http:/public-snapshots false true 1 10 01 10 0公司内部仓库使用(续)激活配置:development public-snapshotsPS:内部仓库的优点:内部仓库的优点:为内部提供安全的、团队易于协作开发的管理方案 加速Maven构建 提高稳定性,增强控制 可以部署第三方构件 节省外网带宽,降低远程中心仓库负载 1 10 01 10 0公司内部仓库使用总结p重点1:向内部仓库发布构件 使用deploy命令分
37、发,但确保服务器地址和认证信息(账号和密码)。即pom.xml中配置标签,setting.xml配置标签 如果要发布第三方构件,可以进入Nexus服务器管理界面添加,也可以使用命令,具体参考官方文档。p重点2:设置镜像,使得内部开发人员只一个出入口 在setting.xml中配置、标签 镜像设置后,可在Eclipse的Maven Repositories窗口中管理本地仓库、镜像库的索引。1 10 01 10 0项目打包生命周期JAR:将class压缩成JAR包POM:构件为自己本身Maven Plugin:Maven插件,如Jetty插件EJB:企业级JavaBean,支持EJB2、EJB3W
38、AR:Web工程包EAR:JavaEE结构体其它(RAR,SAR,SWF):理论上只要有插件支持即可 1 10 01 10 0项目通用生命周期process-resources复制并处理资源文件,至目标目录,准备打包。compile 编译项目的源代码。process-test-resources复制并处理资源文件,至目标测试目录。test-compile编译测试源代码。test使用合适的单元测试框架运行测试。这些测试代码不会被打包或部署。install将包安装至本地仓库,以让其它项目依赖。deploy将最终的包复制到远程的仓库,以让其它开发人员与项目共享。1 10 01 10 0生成站点 项目信息 组织信息 团队信息 各种报表 1 10 01 10 0Maven开发最佳实践现场动手 1 10 01 10 0Maven高级主题 仓库管理 骨架生成 插件开发 SCM集成 持续构建