Maven学习笔记 (颜群老师讲解)

颜群老师讲解,视频地址:https://ke.qq.com/course/303156?taid=2222959108595764

一片很明白的博文:https://blog.csdn.net/qq_25827845/article/details/78988909

  • maven 简介:

  Maven 翻译为"专家"、"内行",是 Apache 下的一个纯 Java 开发的开源项目。基于项目对象模型(缩写:POM)概念.

自动化构建工具(其它的类似的这种工具 make-ant-maven-gradle) gradle最新,但是学习难度大

  • maven作用:

 Maven 是一个项目管理工具,可以对 Java 项目进行构建、依赖管理。   

             i: jar包管理(依赖管理)

            说明: Maven在进行配置好gav(坐标)之后,运行相应的命令后自动给我们下载jar包,但是有很多的包都是依赖别的jar包的,比如commons-fileupload.jar 会关联comments-io 包,有了Maven,它会自动关联下载所有依赖的Jar,并且不会冲突,this is the NB for Maven。

            ii: 将项目拆分成若干个模块

             说明:为什么这么干 ?因为很多互联网公司的项目都是一个十分巨大和复杂的工程,我们不止可以对项目进行分层,还可以将一个巨大的项目进行拆分,拆成多个比较小的项目,如下图,一个项目可分多层,比如UI层,Service层和Dao层等,随着项目的跟进,每一层代码都很大,整个项目就特别大,然后就想起来把一个大项目分解成多个小项目,Maven就是可以实现。

  1. maven具体功能

清理clean:删除编译的结果,为重新编译做准备。

编译compile:java->class  类到class文件的过程

测试test: 针对于项目中的关键点进行测试,亦可用项目中的测试代码去测试开发代码;

报告:有测试就有报告,将测试的结果进行显示

打包package: 将项目中包含的多个文件压缩成一个文件, 用于安装或部署。 (java项目为-jar、web项目-war,war包可以放在web容器内直接运行)

安装install:将打成的包,放到本地仓库,供其他项目使用。比如a,b,c三个项目,dao,service,ui,三个项目有依赖,将三个项目打成包放到本地仓库供其它去使用

部署deploy:将打成的包 ,放到服务器上准备运行。

所以来说:Maven就是将原产品变成可发布的项目,将java、js、jsp等各个文件 进行筛选、组装,变成一个 可以直接运行的项目。

  1. maven仓库:

引入仓库的原因:

            eg 我的计算机上有多个A,B,C项目,然后我这三个项目都需要abc.jar,如果没有一个公共的存储jar包的地方,每一个项目在进行引入jar包的时候都需要进行联网进行下载jar包,比较费时间,费事费力费空间。Maven的做法是在我们的计算机内,开辟一片空间,一个文件夹内,把所有通过Maven进行管理的项目中需要的jar包,放在一起进行存储,A项目运行的时候需要abc.jar,首先去本地仓库进行寻找,如果有直接下载到项目里,没有再去中央仓库(远程仓库)进行查找并下载,当B项目在运行的时候需要abc.jar,会先去本地仓库查找,如果有就直接拿来下载到项目,没有就去远程中央仓库进行下下载。

本地仓库:在本机上,maven存储jar包的地方,

远程仓库:私服(见最后附件),中央仓库、其他公用库等

仓库还有一种结构:   可以通过nexus进行私服的架构  ,多一种选择模式。

  1. 本机maven环境设置:

下载配置maven

Binary:二进制   Source:源代码   Zip是windows  Gz是Linux

下载到本地硬盘上,压缩版解压就行,我放在了D盘根目录:

    a.配置JAVA_HOME

    b.配置MAVEN_HOME    :    D:\apache-maven-3.5.3\bin       【M2_HOME(或者配置这个)】

    c.配置path :        %MAVEN_HOME%\bin    

    d.验证 :        mvn -v

    e.配置本地仓库  maven目录/conf/settings.xml

        默认本地仓库 :C:/Users/YANQUN/.m2/repository

        修改本地仓库为:  <localRepository>D:/loc_lib</localRepository>

默认的本地仓库没改之前是下面这个样子: 我的电脑上就是 user/zqbig/.m2/repository  

  1. maven相关约定

首先需要知道一个事情,约定优于配置

三种方式:【硬编码的方式(写死代码),配置的方式(xml配置),约定方式】

Maven约定的目录结构如下

约定结构

maven约定的目录结构:

 项目

 -src                

 ----main                         【程序功能代码】

           ----java                【java代码  (Hello xxx)】

           ----resources       【资源代码、配置代码】

 ----test                           【测试代码】

           ----java            

           ----resources   

-target                            【将源码编译后的结果放在这个文件夹下】

    

pom.xml                         【和src同级目录,项目对象模型】 

讲一下什么是pom:project object module 项目对象模型 ,不同于面向对象等相关思想,将项目看成节点或者对象,

   <groupId>域名翻转.大项目名</groupId>
    <artifactId>子模块名</artifactId>
    <version>版本号</version>

     <groupId>org.lanqiao.maven</groupId>    
     <artifactId>HelloWorld</artifactId>
     <version>0.0.1-SNAPSHOT</version>

在创建好相关项目后,并编写pom文件,执行Maven命令常用命令,我们在pom所在目录至此那个cmd操作
: 注意必须和项目中的pom是同级目录才能执行。

mvn compile :进行项目编译,首次执行会去本地仓库根据本地仓库gav找依赖的jar,有就直接拿来用,没有去中央找,然后再用。compile只编译main目录,会忽略Test目录中的代码

其它命令:

mvn test :进行测试编码的编译,出现上图的代码,说明编译成功了
mvn package: 进行打包,只有在通过测试之后,才能进行打包。如果只是java文件,那么就打成了jar包,如果是web项目,则会打包成war包
mvn install: 打包之后,通过mvn install 将打好的包安装到本地仓库,供其它项目或者模块使用。
mvn clean:删除target目录(删除编译文件的目录)
运行mvn命令,必须在pom.xml文件所在目录
  1. maven生命周期(了解):

生命周期和构建的关系:生命周期中的顺序:a b c d e

当我们执行c命令,则实际执行的是 a b c

clean lifecycle :清理分成三个阶段:1:pre-clean  2.clean  3.post-clearn

        default lifecycle :默认(常用)site lifecycle:站点 和发布站点有关

        pre-site   site   post-site  site-deploy(部署)

        再次强调:在pom.xml中增加完依赖后 需要maven - update project

  1. Maven

最重要的部分:依赖

1.依赖的有效范围

在pom文件中 dependency 的 scope标签就是依赖范围 。

Maven在编译、测试、运行项目时,各自使用一套classpath,所以依赖jar的scope定义了依赖的范围,定义了有效性的范围

例如:A 项目依赖于Junit的相关jar包

        <dependency>

            <groupId>junit</groupId>

            <artifactId>junit</artifactId>

            <version>4.0</version>

            <scope>test</scope>

        </dependency>

test就是在测试的时候可以拿到A.jar,然后在compile 和其它

  • compile: 编译依赖范围(Default,大多数情况下我们都是在使用compile编译范围)
  • test: 测试依赖范围 (编译主代码和运行时无效)
  • provided: 已提供依赖范围(就是说在运行的时候容器已经给我们提供该依赖了,比如说servlet-api)

provided 具体案例:servlet-api.jar  ,这个jar在我们开发的时候需要引入,在测试的时候也需要用到,但在部署和运行的时候,web容器自带这个jar包,所以在运行的时候是不需要依赖拿到这个jar的。

2.依赖的传递性

eg:A->b->c   A依赖于B,B依赖于C,如果试A依赖于C成立,则需要B依赖于C的范围必须是compile

3.依赖调解

eg.HelloWorldTime ->HelloWorld2 ->junit

看上面的例子,如果两个项目都引入的Junit ,那么maven是如何来避免 Jar冲突的呢。

两个原则,原则一:路径最短,

如下图:HelloWorldTime 依赖于HelloWorld,然后HelloWorld依赖于junit4.0。然而HelloWorldTime自己有添加的依赖Juit3.8 ,这个时候Maven 会在HelloWorldTime选择用哪个呢?答案是Junit3.8。

原则二:路径长度相同的

如下这种情况:

i.在同一个pom.xml文件中有2个相同的依赖(覆盖):后面声明的依赖 会覆盖前面声明的依赖 (严禁使用本情况,严禁在同一个pom中声明2个版本不同的依赖)

ii.如果是不同的 pom.xml中有2个相同的依赖(优先):则先声明的依赖 ,会覆盖后声明的依赖

存在:A->-B>-C->X(1.0)和A->D->X(2.0)
         原则:路径最近原则(指依赖通过几层传递性依赖引入),X(2.0)将会被解析
存在:A->B->Y(1.0)和A->C->Y(2.0)
         原则:第一声明优先原则,哪个现在pom中声明(也就是在pom文件的上边),
就以哪个为准(Maven2.0.9开始使用,在此之前是不确定的,导致构建项目具有一定的随机性)

3. 依赖排除:

我们通过在pom中配置<dependency></dependency>来引入依赖,但是该依赖存在多个传递性依赖,如果某个间接依赖不是我们需要的,影响到了我们项目的正常构建,那么我们可以使用<exclusions><exclusion></exclusion></exclusions>来干掉它。示例如下:

 <dependency>
            <groupId>com.xx.miliao</groupId>
            <artifactId>xx-serviceapi</artifactId>
            <exclusions>
                <exclusion>
                    <artifactId>xx-thrift-micloud-common</artifactId>
                    <groupId>com.xx</groupId>
                </exclusion>
                <exclusion>
                    <artifactId>thrift</artifactId>
                    <groupId>org.apache.thrift</groupId>
                </exclusion>
                <exclusion>
                    <groupId>com.xx</groupId>
                    <artifactId>ipWrapper</artifactId>
                </exclusion>
            </exclusions>
  </dependency>
  

在上边的配置中,我们引入了xx-serviceapi的依赖,但是我们将该依赖所引入的org.apache.thrift和ipWrapper依赖都给排除掉了,这两个依赖将不会出现在我们构建的项目中。   

 

4.归类依赖: 通过Maven统一配置各需要jar和plugs等内容的的版本,  归类依赖看着高大上,其实说白了就是为了统一简单的管理依赖版本,如果某些依赖的version都是一致的或者是存在某些特殊的关系,我们可以在pom中使用<properties></properties>配置一些变量,在下边的时候使用$变量名来搞定。

这个profiles 可以配置jdk等很多属性,也可以对一些依赖的版本号进行配置 ,比如统一编码,

比如下方为某个项目中对junit版本进行统一配置,通过properties下设置标签和标签内容来设定 版本,然后在进行配置依赖的时候,version就可以选择已经定义好的值。 

通过maven统一jdk版本:
   <profiles>
    <profile>  
        <id>jdk-18</id>   版本号
        <activation>  
            <activeByDefault>true</activeByDefault>    激活
            <jdk>1.8</jdk>  
        </activation>  
        <properties>  
            <maven.compiler.source>1.8</maven.compiler.source>  
            <maven.compiler.target>1.8</maven.compiler.target>  
            <maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>  
        </properties>   
    </profile>  
</profiles>

 


对于依赖传递性的问题 :A-->B-->Junit   这种集成关系,如果希望A也依赖于Jnit ,那么需要B和Junit的依赖范围为compile.这就很麻烦。

 Maven 提出了一种 继承的概念

   在上边的学习中,我们介绍了Maven是一种强大的构建工具,能够帮助我们自动下载构件,并且通过给每一个构件确定其坐标,实现了构件在仓库中的存储。正是Maven的生命周期和插件的互相绑定才使得我们可以非常愉快的完成项目的构建。在实际的项目中,我们往往会建立多个模块(module)。我们在本文中要介绍的聚合和继承就特别适合多个模块的协同工作。[摘抄]  

 

Maven的继承特性可以将各个模块相同的依赖和插件配置提取出来,在简化POM的同时还可以促进各个模块配置的一致性。

eg: A-->B ,A继承与B,则 B是一个父类的存在,

A会继承所有B 的依赖。 在创建B的时候我们称之为父工程,在创建的时候父工程不需要进行编码之类的东西,只添加依赖,所以在父工程的打包类型packageing选择 pom类型(java是jar,web项目是war)

父工程可以用来添加所有的依赖,子工程用来实际编码,不用每个工程都添加相应的依赖【可不可以?】

B的pom文件

父工程的pom.xml中多了这么一个标签:

子工程需要怎么操作?

需要在子工程中的配置父工程的gav坐标,你还得告诉子工程你有爹了

标签<parent></parent>就是用来告诉他有爹了。

如果在配置的时候,父工程的groupId和version等属性 如果相同,在子工程里,其实这些信息可以省略,因为他会继承父工程的。

这个继承的时候和类继承类似,在上面我们进行依赖性的测试时,如果A-->B-->junit 

原来单纯依赖的时候,B依赖于Junit的时候范围为compile,那么在A工程的类包中可以看到junit的jar,

但是在继承的时候不一样,我们会看不到。但是有时候父工程的依赖特别多,我们并不想全盘接受。

继承实现步骤:
1.建立父工程: 父工程的打包方式为pom
2.在父工程的pom.xml中编写依赖:
<dependencyManagement>
 <dependencies>
 <dependency>
3.子类:
  <!-- 给当前工程 继承一个父工程:1加入父工程坐标gav   2当前工程的Pom.xml到父工程的Pom.xml之间的 相对路径  -->
     <parent>
         <!-- 1加入父工程坐标gav -->
           <groupId>org.lanqiao.maven</groupId>
          <artifactId>B</artifactId>
          <version>0.0.1-SNAPSHOT</version>
         <!-- 2当前工程的Pom.xml到父工程的Pom.xml之间的 相对路径 -->
          <relativePath>../B/pom.xml</relativePath>
     </parent>
4.在子类中 需要声明 :使用那些父类的依赖
  <dependency>
 <!-- 声明:需要使用到父类的junit (只需要ga) -->

Maven的聚合特性可以帮助我们把项目的多个模块聚合在一起,使用一条命令进行构建,即一条命令实现构建多个项目;

我们在一个项目中会存在模块A和模块B,在各自的项目目录下,我们可以分别通过命令 mvn clean package 来构建各个模块,但是如果我们想将这两个模块一起构建呢?

       答案是我们需要建立一个模块C做为一个聚合模块。

C模块的打包方式必须为pom。

 聚合模块和父模块经常可以做到合二为一。


eg.项目HelloWorld2与 项目HelloWorldTime, 如果想让这两个项目,第一个项目中的类,第二个类可以用,那么可以把HelloWorld 打成包,放在本地仓库中,然后在第二个项目HelloWorldTime 项目的pom中,添加这个项目的依赖。

HelloWorld2 中pom定义的项目坐标如下:

在执行完 install之后,我们可以从本地仓库D:/loc_lib/org/lanqiao/maven/下 找到要生成的jar包

然后在HelloWorldTime中的pom进行依赖引入;如下: 上部红色框是HelloWorldTime 自己的,下面是依赖的HelloWorld的


用Myeclipse 创建一个Maven项目,空白处右键

在eclipse中创建Maven工程,需要进行配置,修改本地的仓库。

eclipse会自带Maven,我们进行选择自己安装的Maven。

更换之后,在下面会有一个user Settings

 

浏览选择自己Maven安装路径conf目录下的 settings.xml(这里面有我们配置的<localRepository>D:/loc_lib</localRepository>);

选中之后,最下面的Local Repository 会自动的变成 我们本地仓库的目录。

 

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值