Maven工具系列(三)--详解Maven原理,只要一篇就够了!

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

01Maven核心概念

1.项目对象模型

 

640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1

 

    

说明:

        maven根据pom.xml文件,把它转化成项目对象模型(POM),这个时候要解析依赖关系,然后去相对应的maven库中查找到依赖的jar包。

在clean,compile,test,package等阶段都有相应的Plug-in来做这些事情。而这些plug-in会产生一些中间产物。

 

2.插件的位置

        在maven解压后的位置E:\apache-maven-3.5.0\bin(安装目录)有一个bin文件夹,里面有一个文件m2.conf文件:

set maven.home default ${user.home}/m2,其中该路径指明了仓库的存储位置。在本地仓库下面所有的plugins都在:

640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1

 

3.maven的内置插件

        我们在执行maven命令的时候 mvn  clean  compile package,maven会通过自己内置插件帮我们执行 项目的清理 编译 打包工作,这些也是通过maven的内置插件实现的。

640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1

 

4.插件的配置

                                                      

 

02.Maven生命周期和坐标相关概念

1.生命周期

       先来一张图表示maven的生命周期:

640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1        

一个完整的项目构建过程通常包括清理、编译、测试、打包、集成测试、验证、部署等步骤,Maven从中抽取了一套完善的、易扩展的生命周期。Maven的生命周期是抽象的,其中的具体任务都交由插件来完成。Maven为大多数构建任务编写并绑定了默认的插件,如针对编译的插件:maven-compiler-plugin。用户也可自行配置或编写插件。

        Maven 拥有三套相互独立的生命周期: clean、default 和 site, 而每个生命周期包含一些phase阶段, 阶段是有顺序的, 并且后面的阶段依赖于前面的阶段. 而三套生命周期相互之间却并没有前后依赖关系, 即调用site周期内的某个phase阶段并不会对clean产生任何影响.

        clean 

clean生命周期的目的是清理项目: 

 mvn clean;

default 

default生命周期定义了真正构建时所需要执行的所有步骤: 

mvn clean install;

        site 

site生命周期的目的是建立和发布项目站点: Maven能够基于POM所包含的信息,自动生成一个友好的站点,方便团队交流和发布项目信息 

 mvn clean deploy site-deploy;

 

2.Maven坐标

类似在平面几何中坐标(x,y)可以标识平面中唯一的一点, Maven世界拥有大量构建,我们需要找一个用来唯一标识一个构建的统一规范

拥有了统一规范,就可以把查找工作交给机器:

 groupId:定义当前Maven项目隶属项目  (实际对应JAVA的包的结构, 是main目录里java的目录结构)。

 artifactId:定义实际项目中的一个模块(项目的唯一的标识符,实际对应项目的名称,就是项目根目录的名称)。

 version:定义当前项目的当前版本。

640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1

        如何发布项目到仓库:

mvn install :发布到本地仓库,一般开始使用
mvn deploy : 发布到远程仓库,test,生产,uat环境等使用

    

03.Maven依赖

1.maven依赖的几个特性

    1.1. 依赖范围 -scope标签

       maven在构建过程有3套classpath,我们会根据配置依赖的范围 依赖不同的classpath,如下图:

640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1

compile:默认是compile,对 编译 测试 运行 都有效。

 

provided:对编译和测试classpath有效,运行的时候不需要加入,例如 jsp 依赖 searvlet api ,比如我们在编译和测试的时候有效但是在运行的时候  容器已经提供servletapi,如果加入会造成冲突。

 

runtime:只在测试和运行时 有效,比较典型的例子 jdbc api,只有在启动代码测试或者运行的时候才会启用。

 

test:只会在测试时有效,比较典型例子 就是junit ,只有再测试的时候 才会启用。

 

     1.2 依赖传递

       比如我们引入某一个依赖spring-test,依赖传递特性会很方便帮助我们下来它相关的依赖,而不必有时会因为引入jar有问题而烦恼,但是也有弊端,存在一些不必要的依赖,可能会造成冲突。

640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1

     1.3 依赖排除 -exclusion标签

       依赖排除的特性 也是为了解决依赖冲突的一个方法,很方便去除依赖传递过程中不必要的依赖。在下面依赖冲冲突会用到 该标签。

 

640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1

    1.4 依赖冲突产生原因

       使用maven久了会发现存在依赖冲突的问题,由于依赖的传递特性会引入很多隐式的依赖和现有显示jar版本     所冲突,从而造成版本冲突的问题。要解决这个问题,首先就是要查看pom.xml显式和隐式的依赖类包,       然后通过这个类包树找出我们不想要的依赖类包,手工将其排除在外就可以了。

 

2.依赖冲突的解决     

    2.1两个基本原则:

    1).短路优先原则      

  A->B->logback-1.0.jar  A->logback-1.1.jar

    2).先声明先优先原则(先解析先引用)

       与项目A pom中配置 引用坐标的顺序有关,如果依赖B在C前的话 就优先B,反之...

   A->B->logback-1.0.jar   A->C->logback-1.1.jar

    2.2 实战

        创建三个maven工程  

        maven-01,maven-02,maven-03

        1).三个工程依赖结构:   

       maven-01依赖 spring-test,maven-02,maven-03 (maven-02/03需要首先提交本地仓库,maven-01才能找到 ,可以参考寻找构件过程:1.3 仓库寻找构件过程) ;

         maven-02依赖commons-logging-1.1.1;

        maven-03工程依赖 commons-logging-1.1.3。

    2.2.1 冲突解决办法:     

        短路优先原则:

         maven-01->spring-test->spring-core->commons-loggings-1.2(依赖深度3);

        maven-01->maven-02->commons-loggings-1.1.1(依赖深度2);

                所以maven01工程依赖的commons-loggings-1.1.1;


       先引用先优先的原则:

 

         maven-01->spring-test->spring-core。

         maven-01->maven-02->commons-logging-1.1.1。

         maven-01->maven-03->commons-logging-1.1.3。

如果pom先依赖maven-02则 依赖commons-logging-1.1.1 依赖;反之,如果pom先依赖maven-03则 依赖commons-logging-1.1.3 依赖;

      org.springframework      spring-test      4.2.2.RELEASE                                    commons-logging              commons-logging                              com.sohu.train      maven-03      0.0.1-SNAPSHOT              com.sohu.train      maven-02      1.0-SNAPSHORT    

 

04.聚合与继承

1.聚合     

     Maven的聚合特性(aggregation)能够使项目的多个模块聚合在一起构建, 而继承特性(inheritance)能够帮助抽取各模块相同的依赖、插件等配置,在简化模块配置的同时, 保持各模块一致.

      随着项目越来越复杂(需要解决的问题越来越多、功能越来越重), 我们更倾向于将一个项目划分几个模块并行开发, 如: 将code_project项目划分为redis、kafka和web三个模块(按照功能进行划分), 而我们又想一次构建所有模块, 而不是针对各模块分别执行$ mvn命令. 于是就有了Maven的模块聚合 -> 将code_project作为聚合模块将其他模块聚集到一起构建:

640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1

2.继承

    在面向对象中, 可以通过类继承实现复用. 在Maven中同样也可以创建POM的父子结构, 通过在父POM中声明一些配置供子POM继承来实现复用与消除重复。(实际项目运用 的)

    父工程:

           ../maven-01      ../maven-02      ../maven-03       

    子工程:

          com.zfr.aaron          maven-test          0.0.1-SNAPSHOT          ../maven-aggregate/pom.xml      

 

05.pom文件配置详解和settings文件配置详解

详解文件,地址信息:

https://github.com/zfrHJ/aaron_architecture_road/tree/master/environmental_construction/maven

maven全局配置文件settings.xml详解:https://www.cnblogs.com/jingmoxukong/p/6050172.html

 

06.Maven Plugin 开发

       几乎100%的场景都不用我们自己开发Maven插件, 但理解插件开发可以使我们更加深入的理解Maven. 下面我们实际开发一个用于统计代码行数的插件 lc-maven-plugin.需要的参考如下资料:

(https://www.cnblogs.com/yulonglyw/p/8550603.html)

 

补充知识点:

maven私库操作:

(https://www.cnblogs.com/hujiapeng/p/7127213.html)

欢迎关注GitHub地址:https://github.com/zfrHJ/aaron_architecture_road

Maven工具系列(三)--详解Maven原理,只要一篇就够了!_第1张图片

转载于:https://my.oschina.net/u/2380961/blog/3039875

你可能感兴趣的:(Maven工具系列(三)--详解Maven原理,只要一篇就够了!)