maven—初级篇
一些零散的笔记:
mvn命令若干:
mvn -h,不会用时,可寻求帮助。
mvn clean compile,将.java类编译为.class文件;
mvn clean test, 执行单元测试。本质上,还是执行了一个完整的生命周期,clean:clean, resources:resources, compiler:compile, resources:testResources, compiler:testCompile
mvn clean package,进行打包。
mvn clean install –Dmaven.test.skip
mvn clean install,将某jar包安装到maven本地仓库中。
mvn archetype:generate,快速的搭建项目骨架,输入一些groupId/artifactId/version等信息,由mvn插件自动生成一些必要的依赖和项目骨架。
这三个标签,形成一个小单元(所谓的依赖的“基本坐标”)
<groupId>, 定义组,如com.googlecode.myapp
<artifactId>, 定义组内一个具体的条目,如helloworld。(com.googlecode.myapp.helloworld)
<version>,定义个版本号。一般开发中的包,1.0-SNAPSHOT即用snapshot作为后缀。
以下为非必须(但要了解):
<type> ,package类型,一般不用写,默认是jar。还有,jar/war/pom/maven-plugin/ear等。
<scope>,依赖范围,我简记为“能见度”。例如,
test=测试。仅对测试类有效,在java类中引入会报错的。例如,JUnit
compile=编译+测试+运行,默认不写则是这种编译方式,对于编译、测试、运行都有效。例如,spring-core
provided=编译+测试。对于编译和测试有效,运行时无效。例如,servlet-api,其在编译和测试时需要使用,但在运行时由于容器已经提供,所以不需要mvn重新的引入一遍。
runtime=运行时。例如,JDBC驱动实现,类的编译只需JDK提供的JDBC接口即可,在真正执行测试或运行时才需实现上述接口的具体JDBC驱动。
system=// 这个可以不用理解。
import=导入。
<optional>,可选依赖。例如,A->B,B->C(optional=true),那么A将对C不形成传递依赖。
<exclusions>,排除依赖。例如,A->B, B->C(1.0-SNAPSHOT),而我实际想用C2.0,那么就需要在B中将C给排除出去。
对于同一模块的jar包,可以在pom中通过统一变量进行定义
声明<properties><springframework.version>2.5.6</…>
引用<version>${springframework.version}</…>
传递依赖(->表示依赖):
A->B,而实际上,B->C,那么A对B是直接依赖,对C是传递依赖。其“能见度”如下表所示。第一列为A->B,对一行为B->C,表格中内容为,A->C。
compile | test | provided | runtime | |
compile | compile | no | no | runtime |
test | test | no | no | test |
provided | provided | no | provided | provided |
runtime | runtime | no | no | runtime |
依赖调解:
A->B->C->X(1.0)
A->D->X(2.0)
那么,按路径最短者生效(即X2.0).
A->B->Y(1.0)
A->C->Y(2.0)
那么,mvn2.0.8及之前版本,顺序不确定。mvn2.0.9以后,第一声明者优先。
如何查看依赖:
一个事实:mvn会自动解析所有项目的直接依赖和传递性依赖,并且根据一定规则正确判断每个依赖的范围,对于一些依赖冲突,也能进行调节,以确保任何一个构件只有唯一的版本在依赖中存在。在这些工作之后,最后得到的那些依赖被称为已解析依赖(Resolved Dependency)。
一个命令:mvn dependency:list
一个命令:mvn dependency:tree
一个命令:mvn dependency:analyze
==================以下为进阶===================
生命周期:
public abstract class AbstractBuild(){
public void build(){
initialize(); // 初始化工作
compile(); // 编译
test(); // 测试
package(); // 打包
integrationTest(); // 集成测试
deploy(); // 部署
}
}
这里只是个示意,以说明maven存在的价值、意义和定位。其中的每个步骤,都可以用插件来做。mvn也为我们设置了默认的插件,不过如果想进行个性化的定制,可以自己选择plugin,或者自己写plugin。
1)以下三个生命周期,相互独立,且每个生命周期的每个步骤,均可单独调用(但假如调步骤3的时候,其前的步骤1、2也是会执行的)。
2)注意,在命令行执行mvn命令,本身就是在调用mvn的生命周期哦,可爱吧,呵呵。
clean生命周期
pre-clean
clean
post-clean
default生命周期(从上到下,从左至右的看哦)
validate |
generate-sources |
generate-test-sources |
prepare-package |
pre-interation-test |
initialize |
process-sources(注1) |
process-test-sources |
package(注4) |
integration-test |
generate-resources |
generate-test-resources |
verify |
||
process-resources |
process-test-resources |
install(注5) |
||
compile(注2) |
test-compile |
deploy(注6) |
||
process-classes |
process-test-classes |
|||
test(注3) |
注1:一般来说,对src/main/resources目录的内容进行变量替换等工作后,复制到项目输出的主classpath目录当中去。
注2:一般来说,是编译src/main/java目录下的java文件至项目输出的主classpath目录当中去。
注3:使用单元测试框架运行测试,测试代码不会被打包或部署。
注4:将编译好的代码,打包成可发布的格式,如jar。
注5:将包安装到mvn本地仓库,供本地其他mvn项目使用。
注6:将包复制到远程仓库。
site生命周期
暂略去不谈。
认识插件:
1)在pom中,可自定义插件,并将其绑进生命周期中去。有些插件自己也会有默认的生命周期的,取决于插件自身实现。根据功能,也可以一个插件绑到N个阶段中去。
2)在pom中,可对插件进行全局配置,例如maven-compiler-plugin默认都用JDK 1.5进行。
3)。。。差不多了,先写到这里。