初识maven
一、maven的生命周期
http://juvenshun.iteye.com/blog/213959
之所以先说生命周期,个人认为不论是maven的使用还是原理都是依照生命周期来展开的。
三套相互独立的生命周期 :clean lifecycle ; default lifecycle ; site lifecycle
clean lifecycle:
pre-clean
clean
post-clean
site lifecycle
pre-site
site
post-site
site-deploy 将生成的站点文档部署到特定的服务器上
default lifecycle
default lifecycle
validate
generate-sources
process-sources
generate-resources
process-resources 复制并处理资源文件,至目标目录,准备打包。
compile 编译项目的源代码。
process-classes
generate-test-sources
process-test-sources
generate-test-resources
process-test-resources 复制并处理资源文件,至目标测试目录。
test-compile 编译测试源代码。
process-test-classes
test 使用合适的单元测试框架运行测试。这些测试代码不会被打包或部署。
prepare-package
package 接受编译好的代码,打包成可发布的格式,如 JAR 。
pre-integration-test
integration-test
post-integration-test
verify
install 将包安装至本地仓库,以让其它项目依赖。
deploy 将最终的包复制到远程的仓库,以让其它开发人员与项目共享。
(执行任意一个阶段时,都会执行其前面所有阶段)
二、maven怎么使用
(一)常用命令
1.创建项目(java项目 webapp项目 )
mvn archetype:generate -DgroupId=项目用途(非盈利org/商业com).公司名 -DartifactId=项目名 -DarchetypeArtifactId=maven-archetype-quickstart /maven-archetype-webapp -DinteractiveMode=false
(maven3.0.5以上版本舍弃了create,使用generate生成项目)
1) 常用原型:maven-archetype-quickstart / maven-archetype-webapp
a). maven-archetype-quickstart
src/main/java -->App.java
src/test/java -->AppTest.java 放junit测试
pom.xml里包含Junit依赖声明
b).maven-archetype-wewbapp
src/main/java
src/main/resource 放配置文件的
src/main/webapp
src/test/java
pom.xml:package为war 包含junit
(实际开发中,创建的java项目,也会补齐resources文件夹)
2)多项目集成创建
父类项目的pom.xml中pockage改成 pom 表示是一个被继承的模块
子类 中 groupId version 删除 添加依赖dependency (domain(域模型层)、dao(数据库访问层)、service(业务逻辑层)、web(表现层))
2.编译项目
目录切换到artifactid对应的目录下, mvn clean compile 生成target文件夹 里面都是编译后的文件。(.class)
多项目集成编译: 需要在webapp类型的maven里添加jetty插件plugin配置 然后项目打包 mvn clean install 生成web项目的war文件 放在tomcat的webapps下 tomcat访问
(install执行的时候,会自动先执行编译,测试,打包)
3.清除: 目录切换到artifactid对应的目录下, mvn clean 删除target文件
4.测试编译 目录切换到artifactid对应的目录下, mvn test 会执行src/test/java下的Junit文件。 执行前会自动编译
5.打包 目录切换到artifactid对应的目录下, mvn package 会将项目打包成jar包放在target文件夹下,执行前会执行编译和测试命令
6.安装 目录切换到artifactid对应的目录下, mvn install 会将项目jar包安装到本地仓库中,以便其他项目使用,执行此命令之前会先执行编译,测试,打包命令
三、maven内部运行原理解析
生命周期中 约定的规范相当于java中的接口 ,并没有实质性的行为。而是在命令执行相应阶段的时候,则用到了goal,一个goal在maven中就是一个Mojo。(Maven oldJava
object)。Mojo抽象类中定义了一个execute()方法,一个goal的具体动作就是在execute()方法中实现。实现的Mojo类应该放在maven plugin里,所谓的plugin其实也就是一个maven项目,只不过这个项目会引用maven的一些API,plugin项目也具备maven坐标。
在执行具体的构建时,我们需要为lifecycle的每个phase都绑定一个goal,这样才能够在每个步骤执行一些具体的动作。比如在lifecycle中有个compile phase规定了构建的流程需要经过编译这个步骤,而maven-compile-plugin这个plugin有个compile goal就是用Javac来将源文件编译为class文件的,我们需要做的就是将compile这个phase和maven-compile-plugin中的compile这个goal进行绑定,这样就可以实现Java源代码的编译了。
四、maven作用
项目管理工具 “约定优于配置”
1.项目构建 maven能做到的是一键完成 编译/测试/打包/代码生成 这一系列功能
好处:省区程序员手动操作这些的时间。标准的日志文件 可用在团队分工开发,也可以应用于多个项目,节省学习脚本,了解构建项目的时间
2.管理依赖 dependency
坐标(groupId,artifactId,version这三个就可以确定一个依赖)
好处:避免jar包依赖版本不一致,版本冲突,依赖过多
3.项目信息管理
统一的标准:项目文档。测试报告,静态分析报告,源码版本日志,项目目录结构,测试用例命名方式等
好处:方便项目分工,提高开发效率
4.maven+eclipse
maven构建项目骨架,eclipse分工开发
五、maven仓库
1.仓库布局:
groupId/artifactId/version/artifactId-version.packaging
源码中拼接的方法是:pathOf(Artifact artifact) 三个静态变量 . \ -; new StringBuilder ; append
2.获取插件或者依赖的方式
先从本地仓库查找,如果没有,根据坐标从远程仓库下载,下载到本地仓库后,使用本地仓库构建
ctrl+c终止下载
(maven2获取的是最新版本的构件,而maven3获取的是最新的稳定版本构件)
3.关于仓库管理器
Nexus 仓库管理器 由于远程仓库下载次数频繁,带宽消耗大 Nexus indexer
实际开发中建议定时清理本地仓库 而这项工作则可以交由Nexux,所有的依赖从仓库管理器抓取
六、maven内置变量
http://www.cnblogs.com/zxf330301/p/5983771.html
Maven提供了三个隐式的变量可以用来访问环境变量,POM信息,和Maven Settings
env
env变量,暴露了你操作系统或者shell的环境变量。便 如在Maven POM中一个对${env.PATH}的引用将会被${PATH}环境变量替换,在Windows中为%PATH%.
projet
project变量暴露了POM。可以使用点标记(.)的路径来引用POM元素的值。
${basedir} 项目根目录
${project.build.directory} 构建目录,缺省为target
${project.build.outputDirectory} 构建过程输出目录,缺省为target/classes
${project.build.finalName} 产出物名称,缺省为${project.artifactId}-${project.version}
${project.packaging} 打包类型,缺省为jar
${project.xxx} 当前pom文件的任意节点的内容
settings
settings变量暴露了Maven settings信息。可以使用点标记(.)的路径来引用settings.xml文件中元素的值。例如${settings.offline}会引用~/.m2/settings.xml文件中offline元素的值。
新手初识,欢迎指正。
maven对项目测试用例命名方式怎么规定规则?
Ant(another neat tools)为什么市场比重大于maven? (ant:数字签名,打包,持续集成,自动化)
maven为什么可以按照生命周期的顺序,,顺序执行?
在仓库布局源码里,为什么使用StringBuilder,而不是使用StringBuffer