• Maven学习笔记


    之前匆匆学了maven,没有记好笔记,结果实习中挺多问题还是得百度解决,今天就系统的回顾一下maven。

     

    一、为什么要学Maven?

    统一管理依赖

    我们现在的项目可能要用到很多框架,项目中依赖的jar包也越来越多,而且jar包之间的依赖关系也很复杂,使用maven可以自动的下载这些jar包并引用、可以很好的自动管理jar包之间的依赖,程序员可以省去很多工作。

    进行项目构建

    可以简化项目的构建过程。当我们使用IDEA进行开发时,项目的构建都是IDEA进行自动完成的,但是如果脱离了IDE就要用专业的构建工具来完成。

    什么是项目的构建? 

    使用原材料生产出一个产品的过程。

    原材料:Java源代码、配置文件、图片等我们开发的东西。

    产品:一个可以运行在服务器上的项目。

    构建过程包含的主要的环节:

    • 清理:删除上一次构建的结果,为下一次构建做好准备
    • 编译:Java 源程序编译成 *.class 字节码文件
    • 测试:运行提前准备好的测试程序
    • 报告:针对刚才测试的结果生成一个全面的信息
    • 打包
      • Java工程:jar包
      • Web工程:war包
    • 安装:把一个 Maven 工程经过打包操作生成的 jar 包或 war 包存入 Maven 仓库
    • 部署
      • 部署 jar 包:把一个 jar 包部署到 Nexus 私服服务器上
      • 部署 war 包:借助相关 Maven 插件(例如 cargo),将 war 包部署到 Tomcat 服务器上

    idea工具maven的Lifecycle功能讲解

    clean:用于清除上次构建生成的所有文件,一般在构建前执行。执行该命令会删除项目路径下的target文件,但是不会删除本地的maven仓库已经生成的jar文件。

    mvn clean

    validate:验证,验证工程是否正确,所需的信息是否完整。

    compile:编译,编译Java源代码成class字节码文件,编译后的class文件会存在target目录下的classes目录中。

    主程序编译:mvn compile

    测试程序编译:mvn test-compile

    主体程序编译结果存放的目录:target/classes

    测试程序编译结果存放的目录:target/test-classes

    test:测试,用合适的测试框架来进行测试,测试compile中编译出来的代码,测试的东西一般不加包和部署。

    mvn test

    测试的报告存放的目录:target/surefire-reports

    package:打包,将工程文件打包为指定的格式,例如JAR,WAR等(项目的pom文件中的packing标签指定打包类型)。存到target目录,并且拥有compile命令的功能进行编译。如果a项目依赖于b项目,打包b项目时,只会打包到b项目下target下,编译a项目时就会报错,因为找不到所依赖的b项目,说明a项目在本地仓库是没有找到它所依赖的b项目,这时就用到install命令。

    verify:验证,检查package是否有效、符合标准。

    install:安装,将项目的包安装到本地仓库中(本地仓库中的目录就是项目的坐标),好让其他项目引用。这个命令包含package,也会将项目打包成jar包或war包到本地仓库中。另外,安装操作还会将 pom.xml 文件转换为 XXX.pom 文件一起存入本地仓库。所以我们在 Maven 的本地仓库中想看一个项目的原始的 pom.xml 文件时,查看对应 XXX.pom 文件即可。

    site:站点,生成项目的站点文档,生成的网站是在项目的“target/site”文件夹。

    deploy:部署,复制最终的包至远程仓库,共享给其它开发人员和项目。

    二、如何学好maven

    maven安装

    安装很简单,就不说了,主要记录一下maven目录下的conf/settings.xml设置文件

    指定本地仓库位置

    本地仓库默认值:用户家目录/.m2/repository。由于本地仓库的默认位置是在用户的家目录下,而家目录往往是在 C 盘,也就是系统盘。将来 Maven 仓库中 jar 包越来越多,仓库体积越来越大,可能会拖慢 C 盘运行速度,影响系统性能。所以建议将 Maven 的本地仓库放在其他盘符下。

    <localRepository>D:\maven-repositorylocalRepository>
    

    配置阿里云提供的镜像仓库

    项目依赖的jar包如果本地仓库中没有,就会远程仓库中找,下载 jar 包默认访问境外的中央仓库,而国外网站速度很慢。改成阿里云提供的镜像仓库,访问国内网站,可以让 Maven 下载 jar 包的时候速度更快。配置的方式是:

    1. <mirror>
    2. <id>nexus-aliyunid>
    3. <mirrorOf>centralmirrorOf>
    4. <name>Nexus aliyunname>
    5. <url>http://maven.aliyun.com/nexus/content/groups/publicurl>
    6. mirror>

    配置jdk版本

    在settings.xml文件中设置会在所有maven项目中都生效,在pom文件中的配置只对当前项目有效。

    1. <profile>
    2. <id>jdk-1.8id>
    3. <activation>
    4. <activeByDefault>trueactiveByDefault>
    5. <jdk>1.8jdk>
    6. activation>
    7. <properties>
    8. <maven.compiler.source>1.8maven.compiler.source>
    9. <maven.compiler.target>1.8maven.compiler.target>
    10. <maven.compiler.compilerVersion>1.8maven.compiler.compilerVersion>
    11. properties>
    12. profile>

    maven的工作机制

    在项目的pom文件中定义好依赖的坐标后,先到本地仓库中找有没有,如果没有的话,就到私服中找,如果私服有则直接下载到本地仓库中用,反之则到远程仓库中下载,jar包下载后缓存在私服中(方便使用),最后都将jar包保存到本地仓库中使用。

    maven的私服

    maven的私有服务器,称为私服,是一种特殊的远程仓库,一般在公司中会自己的局域网内搭建自己的私服。

    因为公司中一般会有很多人同时在开发一些项目,如果每个人都去远程仓库下载依赖,那么网络负载就会比较大, 在自己的局域网内搭建了私服,然后常用的依赖上传到私服中,下载访问的速度肯定比较快(提高jar包下载速度)。

    如何配置私服:

    1. <repositories>
    2. <repository>
    3. <id>nexus_coracleid>
    4. <name>coracle private nexusname>
    5. <url>http://xxx:7081/nexus/content/groups/publicurl>
    6. repository>
    7. <repository>
    8. <id>thirdpartyid>
    9. <name>Repository for thirdpartyname>
    10. <url>http://xxx:7081/nexus/content/repositories/thirdpartyurl>
    11. repository>
    12. repositories>

    maven依赖的范围

    标签的位置:dependencies/dependency/scope

    范围可选值:compile/test/provided/system/runtime/import

    默认值:compile

    main目录(空间)test目录(空间)开发过程(时间)部署到服务器(时间)
    有效有效有效有效compile
    无效有效有效无效test
    main目录(空间)test目录(空间)开发过程(时间)部署到服务器(时间)
    有效有效有效有效compile
    有效有效有效有效provided

    总结:

    compile:通常使用的第三方框架的 jar 包,项目在实际运行时要用到的 jar 包都是以 compile 范围进行依赖的,就是需要参与部署到服务器上的。比如 SSM 框架所需jar包。

    test:测试过程中使用的 jar 包,以 test 范围依赖进来,也不会打包进去,不参与部署。比如 junit。

    provided:在开发过程中需要用到的“服务器上的 jar 包”通常以 provided 范围依赖进来。比如 servlet-api、jsp-api,这个服务器上已经有了,tomcat服务器本身里面就有了。而这个范围的 jar 包之所以不参与部署、不放进 war 包,就是避免和服务器上已有的同类 jar 包产生冲突,同时减轻服务器的负担。说白了就是:“服务器上已经有了,你就别带啦!”

    maven依赖的传递性

    在 A 依赖 B,B 依赖 C 的前提下,C 是否能够传递到 A,取决于 B 依赖 C 时使用的依赖范围。

    • B 依赖 C 时使用 compile 范围:可以传递
    • B 依赖 C 时使用 test 或 provided 范围:不能传递,所以需要这样的 jar 包时,就必须在需要的地方明确配置依赖才可以。

    maven依赖冲突的排除

    当 A 依赖 B,B 依赖 C 而且 C 可以传递到 A 的时候,A 不想要 C,需要在 A 里面把 C 排除掉。而往往这种情况都是为了避免 jar 包之间的冲突。

    A项目依赖了B(B依赖了X-1.0),A项目也依赖了C(C依赖了X-2.0),如果X-都能传递到C的话,这样两个X-就会冲突,所以需要排除掉一个,解决包冲突。

    1. <dependency>
    2. <groupId>com.atguigu.mavengroupId>
    3. <artifactId>pro01-maven-javaartifactId>
    4. <version>1.0-SNAPSHOTversion>
    5. <scope>compilescope>
    6. <exclusions>
    7. <exclusion>
    8. <groupId>commons-logginggroupId>
    9. <artifactId>commons-loggingartifactId>
    10. exclusion>
    11. exclusions>
    12. dependency>

    maven的继承

    Maven工程之间,A 工程继承 B 工程

    • B 工程:父工程
    • A 工程:子工程

    本质上是 A 工程的 pom.xml 中的配置继承了 B 工程中 pom.xml 的配置。

    意义:

     在父工程中统一管理项目中的依赖信息,具体来说是管理依赖信息的版本。

    一个项目比较大的,通常要分成好几个模块,每个模块都会维护自己的依赖信息,有些依赖可能都是一样的,使用继承可以统一依赖的版本信息,统一依赖的最优版本组合,通过父工程统一管理维护依赖的信息的组合,可以保证依赖使用的准确性。

    1. <groupId>com.atguigu.mavengroupId>
    2. <artifactId>pro03-maven-parentartifactId>
    3. <version>1.0-SNAPSHOTversion>
    4. <packaging>pompackaging>
    5. <dependencyManagement>
    6. <dependencies>
    7. <dependency>
    8. <groupId>org.springframeworkgroupId>
    9. <artifactId>spring-coreartifactId>
    10. <version>4.0.0.RELEASEversion>
    11. dependency>
    12. <dependency>
    13. <groupId>org.springframeworkgroupId>
    14. <artifactId>spring-beansartifactId>
    15. <version>4.0.0.RELEASEversion>
    16. dependency>
    17. <dependency>
    18. <groupId>org.springframeworkgroupId>
    19. <artifactId>spring-contextartifactId>
    20. <version>4.0.0.RELEASEversion>
    21. dependency>
    22. <dependency>
    23. <groupId>org.springframeworkgroupId>
    24. <artifactId>spring-expressionartifactId>
    25. <version>4.0.0.RELEASEversion>
    26. dependency>
    27. <dependency>
    28. <groupId>org.springframeworkgroupId>
    29. <artifactId>spring-aopartifactId>
    30. <version>4.0.0.RELEASEversion>
    31. dependency>
    32. dependencies>
    33. dependencyManagement>
    1. <parent>
    2. <groupId>com.atguigu.mavengroupId>
    3. <artifactId>pro03-maven-parentartifactId>
    4. <version>1.0-SNAPSHOTversion>
    5. parent>
    6. <artifactId>pro04-maven-moduleartifactId>
    7. <dependencies>
    8. <dependency>
    9. <groupId>org.springframeworkgroupId>
    10. <artifactId>spring-coreartifactId>
    11. dependency>
    12. <dependency>
    13. <groupId>org.springframeworkgroupId>
    14. <artifactId>spring-beansartifactId>
    15. dependency>
    16. <dependency>
    17. <groupId>org.springframeworkgroupId>
    18. <artifactId>spring-contextartifactId>
    19. dependency>
    20. <dependency>
    21. <groupId>org.springframeworkgroupId>
    22. <artifactId>spring-expressionartifactId>
    23. dependency>
    24. <dependency>
    25. <groupId>org.springframeworkgroupId>
    26. <artifactId>spring-aopartifactId>
    27. dependency>
    28. dependencies>

    编写一套符合要求、开发各种功能都能正常工作的依赖组合并不容易。如果公司里已经有人总结了成熟的组合方案,那么再开发新项目时,如果不使用原有的积累,而是重新摸索,会浪费大量的时间。为了提高效率,我们可以使用工程继承的机制,让成熟的依赖组合方案能够保留下来。

    如上图所示,公司级的父工程中管理的就是成熟的依赖组合方案,各个新项目、子系统各取所需即可。

  • 相关阅读:
    el-row一行放置3个el-col,有时出现空行现象
    【数据结构】堆(C语言)
    不知道照片上怎么文字翻译成英文?来看看这篇文章
    C++20之Concept(概念部分)
    vue中的响应式数据vs非响应式数据(添加新商品时,添加的数量,与购物车中的保持一致同步更新)
    案例分析真题--架构师
    Vector容器介绍
    【golang】深入理解Go语言垃圾回收(GC)
    Java IO简介说明
    java中对象的比较
  • 原文地址:https://blog.csdn.net/weixin_52938172/article/details/127663160