maven实战-----读书笔记之第三章~~第五章

第三章  Maven使用入门

1.编写pom.xml

就像Make的makefile,Ant的build.xml一样,Maven的核心是pom.xml,POM(Project Object Model 项目对象模型),定义了项目的基本信息,用于描述项目如何构建以及声明项目依赖等等。代码第一行为xml头,申明了xml文档的版本和编码方式,project是所有pom.xml的根元素,他声明了pom相关的命名空间以及xsd元素,

modelVersion指明了当前pom模型的版本,对于Maven2和maven3而言,他只能是4.0.0,gruodId,artifactId,version定义了一个项目的基本坐标,在maven的世界中,任何的jar,war,都是以这些基本的坐标区分的。

groupId:定义了项目属于哪个组,这些组往往与公司或者所在组织有关联,googlecode建立了一个myapp的项目,那么groupId应该是com.googlecode.myapp。

artifactId:定义了当前maven项目组中唯一的id,图上定义的是hello-world

version:指明当前maven项目的版本。

2.编写测试代码

Maven项目的默认主代码目录是src/main/java,对应的,maven的默认测试代码目录为src/test/java,在编写测试用例之前,应该先创建该文件。下图代码中添加了一个dependencies元素,该元素下包含了dependency元素,用来声明项目的依赖,这里添加了衣蛾依赖groudId是junit,artifactId是junit,version是4.7,有了这段声明,maven会自动下载junit.4.7.jar,下载地址是中央仓库(http://repo1.maven.org/maven2),打开本地仓库,会看到junit/junit/4.7/中,有junit-4.7.pom,junit-4.7.jar,该jar包依赖还申明了一个值为test的scope元素,scope是依赖范围,范围为test,则只是测试范围有效,要是在主代码中import junit的jar包,则会编译错误,如果不申明以来范围,默认的是compile,表示该依赖对主代码和测试代码都有效。  

Maven的核心插件之compiler插件,默认只支持编译java1.3,但是项目一般需要更高的版本,所以修改插件配置让其支持更高版本,图中配置为1.5,

3.项目打包与运行

maven的打包命令:mvn clean package,maven默认的打包类型是jar,打包成jar之后,如果其他项目需要引用该jar包,则可以直接将jar包拷贝到其他项目的classpath路径下,如果想直接引用这个jar包,则需要执行一个安装的步骤,执行mvn clean install;则相应的文件夹可以看到hello world 项目的jar和pom,只有把它安装到本地,其他的maven项目才可以试用它。

maven的命令:mvn clean compile ; mvn clean test ; mvn clean package ; mvn clean install ;执行test命令时,会先执行compile命令,执行package之前会先执行test命令,执行install之前会先执行package命令。

 *默认打包的jar包是不能直接运行的,因为带有main方法的类信息,类信息不会添加到manifest,打开jar包文件中的META-INF/MANIFEST.MF文件,无法看到Main-Class一行,为了生成可执行的jar文件,需要借助maven-shade-plugin,配置如下:

可以看到该jar包下的META-INF的MANIFEST.MF文件多了一行Main-Class

第三章  Maven坐标与依赖

1.依赖的配置

groupId,artifactId,version以来的基本坐标,maven根据坐标才能找到需要的依赖,type:依赖的申明,对应项目坐标定义的packaging,大部分是不需要申明,默认是jar

scope:依赖的范围

optional:标记依赖是否可选

exclusions:用来排除传递性依赖

2.依赖范围

compile:编译依赖范围,如果没有指定scope元素,会默认为compile依赖范围,使用此依赖范围的Maven依赖,对于编译,测试,运行三种classpath都有效,典型的例子就是spring-core,在编译,测试,运行的时候都需要使用该依赖。

test:测试依赖范围,使用此依赖的maven范围,对于测试classpath有效,在编译主代码或者运行项目的使用时将无法使用该类依赖,典型的例子junit,它只在编译测试代码及运行测试的时候才需要。

provided:已提供依赖范围,使用此依赖范围的maven依赖,对于编译和测试classpath有效,但在运行时无效,典型的例子就是servet-api,编译和测试项目的时候需要该依赖,但在项目运行时不需要重复引入,因为容器已经提供该依赖。

runtime:运行时依赖范围,使用此依赖范围的maven依赖,对于测试和运行classpath有效,但在编译主代码时无效,典型的例子就是jdbc驱动的实现,项目主代码的编译只需要jdk提供的jdk接口,只有在执行测试或者运行项目的时候才需要实现上述接口的具体jdbc驱动。

system:系统依赖范围,该依赖与三种classpath的关系,和provide依赖范围完全一致,但是,使用sysyem范围的依赖时必须通过sysyempath元素显性的指定依赖文件的路径,由于此类依赖不是通过maven仓库解析的,而且往往与本机系统绑定,可能造成构建的不可移植,因此谨慎使用,systempath元素可以引用环境变量,如下如所示

import:Mavne2.0.9及以上,导入依赖范围,此依赖不会对三种classpath产生实际的影响,上述的import以外的各种依赖范围与三种classpath的关系如下图所示:

3.依赖传递性

一个项目A引入了很多jar包,一个新开发的项目B需要引用该项目A,那么如果不用maven,就需要去下载A项目需要的jar包,有了maven,就不需要关心A项目引入的依赖,只需要引入A项目,A项目引入的依赖会自动传递。

4.排除依赖

如上图,项目B依赖项目A,项目C,但是由于一些原因,不想引入传递性依赖C,因此要排除 依赖,exclusions元素可以排除多个传递性依赖,申明exclusion的时候不需要申明版本version,这是因为groupId和artifactId就能唯一定位某个依赖,maven依赖中,不可能出现groupId和artifactId相同,版本version却不相同的依赖,所以才会有jar包冲突这一说法。

4.递归依赖

为了避免重复输入一个版本号,还有可能输入不统一的问题,maven为我们提供了定义常量的元素,在properties中定义自己的依赖版本号,然后用${}引入即可,这样就不需要重复写版本号,升级的时候只需要修改常量就可以控制整个的修改。

5.优化依赖

执行命令:mvn dependency:list,输入如下图所示:

 

执行命令:mvn dependency:tree,输出如下图所示,我们项目中没有直接引入spring-aop,spring-core,spring-expression,commons-logging这些jar包,都是间接传递过来的。

输入命令:mvn dependency:analyze,输出如下图所示,该结果中重要的两个部分,Used undeclared dependencies found,表明项目中使用到的spring-context这个依赖,没有显性的申明,这种依赖有潜在的风险,当前项目在直接使用他,这个依赖其实是由springAop-Common间接传递过来的,当我们直接升级依赖的时候,间接传递过来的依赖版本有可能发生变化,这种变化不易察觉,可能导致项目报错,Unused declared dependencies found,项目中未使用到的,但是一般不删除,因为dependency:analyze只会分析编译主代码和测试代码需要用到的依赖,一些执行测试和运行时需要的依赖它无法发现。

原文地址:https://www.cnblogs.com/hejj-bk/p/11417422.html