Maven

一、构建

  1. 含义:指将一个Java项目从源代码编译、打包、部署到目标环境的过程
  2. 目的:将源代码转换为可执行的程序或库,并将其组织成一个可部署的文件或目录结构
  3. 构建步骤:涉及到编译源代码、打包依赖库、生成文档、运行测试、版本控制等一系列步骤
  4. 工具:使用Maven可更方便地管理项目的依赖、打包方式、生命周期等,提高项目的开发效率和可维护性

 

二、Java项目构建流程

  1. 确定需引入的依赖包并将其放入classpath
  2. 确定项目目录结构:src目录存放java源码,resources目录存放配置文件,bin目录存放编译生成的.class文件
  3. 配置环境:JDK版本、编译打包的流程、当前代码的版本号
  4. 使用IDE及命令行方式编译成功

  完成上述步骤才能够让项目在一个独立的服务器上编译、测试、部署

 

三、项目部署与项目发布的区别

  1. 项目部署:指将项目的各个组件和资源在目标环境中进行配置和安装的过程。在部署的过程中,会将项目的文件复制到适当的位置、配置项目的运行环境、启动项目所需的服务等。
  2. 项目发布:指将经过构建的项目从开发环境转移到生产环境的过程。在发布过程中,会将项目的可执行文件、配置文件以及其他相关资源部署到目标服务器上。 项目发布需要先进行项目部署,将软件应用程序部署到目标环境中,然后在目标环境中进行配置和测试,最终才能正式发布给最终用户或客户使用。

 

四、Maven主要功能

  1. 提供标准化的依赖管理
  2. 提供一套标准化的构建流程:编译、测试、打包、运行、发布
  3. 提供一套标准化的项目结构

 

五、Maven默认的标准目录结构

  

    a-maven-projec:项目名称

    pom.xml:项目描述文件

    src/main/java:存放Java源码

    src/main/resources:存放资源文件

    src/test/java:存放测试源码

    src/test/resources:存放测试资源文件

    target:存放所有编译、打包生成的文件

   ~/.m2/repository:Maven默认的本地仓库地址

 

六、POM(Project Object Model,项目对象模型)

  1. POM:Maven项目描述文件,Maven工程的基本工作单元,是一个XML文件。

  2. 包含项目的基本信息(用于描述项目如何构建、声明项目依赖等)。工程的唯一标识:groupId+artifactId+version

   

    modelVersion :指定当前 POM 文件所遵循的 Maven 模型的版本号。它定义了 POM 文件的结构和元素的规范。一般为固定值,通常为4.0.0

    项目信息:

      <groupId>:项目组织唯一的标识符,实际对应项目的包名称,一般分三段,即“域.公司名称.子项目”

      <artifactId>:项目的唯一标识符,实际对应项目名称

      <version>:版本号

    依赖管理:

      <dependencies>:用于定义项目的依赖项,包括所需的库、组件和其他项目等。

      <dependency>:定义单个依赖项的信息,包括 groupIdartifactId 和 version 等。

    构建配置:

      <build>:定义项目的构建配置选项。

      <plugins>:定义构建过程中需要使用的插件。

      <plugin>:定义单个插件的信息,包括插件的 groupIdartifactId、版本号和插件的执行目标等。

    项目模块:

      <modules>:如果项目是多模块项目,可以使用该元素列出各个子模块。

    仓库配置:

      <repositories>:定义项目使用的仓库。

      <repository>:定义单个仓库的信息,包括 URL、认证等。

    环境配置:

      <profiles>:可使用了多个不同的 profile 分别表示开发环境、测试环境和生产环境。每个 profile 中都可以定义相应环境的配置项,如环境变量、数据库连接、日志级别等。通过在构建命令中指定激活的 profile,可以根据不同环境加载相应的配置。

  2. 三种不同层次的POM文件

    (1)项目级 POM(pom.xml):每个 Maven 项目都必须有一个项目级 POM 文件,它位于项目的根目录下。优先级最高。

    (2)用户级 POM(settings.xml):是 Maven 的用户配置文件,位于用户的 ~/.m2 目录下。它可以包含一些用户级别的配置,如个人的 Maven 仓库位置、代理设置、全局插件配置等。优先级高于全局 POM 。

    (3)全局 POM(conf/settings.xml):是 Maven 的全局配置文件,位于 Maven 的安装目录下的 conf 目录中。全局 POM 文件包含了 Maven 的全局配置信息,如全局仓库位置、全局插件仓库位置等。它影响着所有 Maven 项目的构建和管理过程。优先级最低。

    3. 执行任务时,Maven会在当前目录查找pom文件,获取pom文件中的配置信息,然后执行任务。

 

七、Maven构建生命周期

  1. Maven有三套独立的生命周期(lifecycle)。每套lifecycle都由一系列阶段(phase)构成,运行每一个phase,都会将其之前的phase都执行。执行一个phase会触发一或多个goal,goal的命名格式为:abc:xyz。

     (1)Clean Lifecycle :在进行真正的构建之前进行一些清理工作

      • pre-clean:执行一些需要在clean之前完成的工作
      • clean:移出所有上一次构建生成的文件
      • post-clean:执行一些需要在clean之后立刻完成的工作

     (2)Default Lifecycle :构建的核心部分,编译,测试,打包,部署等

      • 验证(validate):验证项目是否正确,所有必要的信息可用
      • 编译(compile):编译项目的源代码
      • 测试(test):使用合适的单元测试框架测试编译的源代码。这些测试不应该要求代码被打包或部署
      • 打包(package):采用编译的代码,并以其可分配格式(如JAR)进行打包。
      • 验证(verify):对集成测试的结果执行任何检查,以确保满足质量标准
      • 安装(install):将软件包安装到本地存储库中,用作本地其他项目的依赖项
      • 部署(deploy):在构建环境中完成,将最终的包复制到远程存储库以与其他开发人员和项目共享。

     (3)Site Lifecycle :生成项目报告,站点,发布站点

      • pre-site:执行一些需要在生成站点文档之前完成的工作
      • site:生成项目的站点文档
      • post-site:执行一些需要在生成站点文档之后完成的工作,并且为部署做准备
      • site-deploy:将生成的站点文档部署到特定的服务器上

  2. 使用命令行编译:mvn+阶段名称+阶段名称

      如mvn clean package:用于构建项目并打包生成可部署的应用程序,运行后,Maven将执行以下操作:

      (1)清理项目目录,删除之前构建生成的目录和文件

      (2)编译项目的源代码,并将编译后的结果放置在target目录中。

      (3)进行单元测试,以确保代码的正确性和质量

      (4)打包项目,生成一个可部署的应用程序文件(例如JAR、WAR或EAR文件)

  3. Maven插件

    Maven生命周期本身不做任何实际工作,每个生命周期的每个阶段实际都是由Maven插件中的插件目标(plugin goal)完成

 

八、Maven仓库

  Maven 有三种类型仓库:本地仓库、中央仓库和远程仓库。

  (1)中央仓库:Maven默认的远程仓库,是一个公共的、全球分布的仓库,所有第三方将自身的jar及相关信息上传到中央仓库。

  (2)镜像仓库:Maven用户自行配置的用于代理远程仓库的本地仓库,用于在下载时替代中央仓库,当 Maven 需要从远程仓库下载依赖或插件时,它首先检查本地镜像仓库是否有所需内容的副本。如果有,Maven 将直接从本地镜像仓库获取内容,而不需要从远程仓库下载。镜像仓库可以提高构建速度和减轻远程仓库的负载。Maven镜像仓库会定期从中央仓库同步信息。

  (3)本地仓库:每个开发人员在自己的计算机上的 Maven 安装中的一个目录。当 Maven 下载项目依赖和插件时,它会将这些文件保存在本地仓库中,对应本地目录(用户主目录的.m2目录)。

  (4)私有仓库:用户自定义的仓库,用于存储私有的、非公开的项目依赖和插件。私有仓库可以是本地的文件系统目录,也可以是远程的 HTTP/HTTPS 服务器。

  当我们执行 Maven 构建命令时,Maven 开始按照以下顺序查找依赖的库:

  (1)在本地仓库中搜索,如果找到了则执行其他操作。如果找不到,则执行步骤2。

  (2)在中央仓库中搜索,如果找到了则下载到本地仓库中以备将来引用。如果找不到,查看是否设置了其他的远程仓库,如果没有设置,则执行步骤3。如果设置了其他的远程仓库,则执行步骤 4。

  (3)如果没有设置其他远程仓库,Maven 将简单的停滞处理并抛出错误(无法找到依赖的文件)。

  (4) 如果设置了其他的远程仓库,且可寻找到需要的依赖文件,则下载到本地仓库以备将来引用,否则 Maven 将停止处理并抛出错误(无法找到依赖的文件)。

 

九、Maven依赖管理

    

  1. 如何查找所需依赖:https://mvnrepository.com/search.maven.org

  2. 依赖包的唯一标识:<groupId>+<artifactId>+<version>

    Maven通过对jar包进行PGP签名确保一个jar包一经发布后就无法修改

    依赖包版本:开发版本:以"-SNAPSHOT"结尾,每次都会重新下载,公开发布版本:不以"-SNAPSHOT"结尾

    一般是通过Maven自动下载它的jar包,并根据pom文件解析依赖,自动把相关依赖包都下载后放入classpath,确保编译和运行时能正确使用它们

  3. 依赖关系的作用范围

    compile:默认,编译时需要用到该jar包、编译、测试、运行时皆可用

    test:compile&test时需要用到该jar包,如JUnit

    runtime:compile时不需要,但run时需要,如MYSQL驱动

    provided:compile时需要用到,但run时由JDK或某个服务器提供,如Servlet API

  4. 依赖冲突

    (1)冲突原理(依赖传递)

     当我们需要依赖A时,在pom.xml中引入A的Jar包;引入的A的Jar包又依赖B的Jar包,Maven在解析pom.xml时,会依次将A、B的Jar包全部都引入进来。
     这样,当A依赖B,B依赖C,C依赖D1(version15),E依赖F,F依赖D2(version16)时。如果pom.xml文件中同时引入A、E两个依赖,根据Maven传递依赖的原则,D1、D2都会被引入,而D1、D2又是同一个依赖D的不同版本。
     当调用D2中的method2()方法,而由于D1是15版本无method2()方法(method1是D升级16版本后增加的方法),这样会导致JVM在加载A中D1依赖时找不到method2方法,报NoSuchMethodError的错误,此时就产生了Jar包冲突。如果D1和D2都有method2()方法,那么在调用method2()方法时不会产生版本冲突的问题。
    (2)冲突解决方案
       Maven默认处理策略
         最短路径优先:Maven 面对 D1 和 D2 时,会默认选择最短路径的那个 jar 包,即 D2。E->F->D2 比 A->B->C->D1 路径短 1。
         最先声明优先:路径一样的情况下,如: A->B->C1, E->F->C2 ,两个依赖路径长度都是 2,最先声明优先。
       移除依赖:用于排除某项依赖的依赖 Jar包
         借助插件:借助Maven Helper插件中的Dependency Analyzer分析冲突的 Jar包,然后在对应标红版本的jar包上面点击execlude,就可以将该jar包排除出去
         手动排除:手动在pom.xml中使用标签去排除冲突的 Jar包(上面利用插件Maven Helper中的execlude方法其实等同于该方法)

       版本锁定原则

        一般用在继承项目的父项目中,这是实际项目开发中比较常见的方法。。

        多模块的项目,可以创建一个公共依赖的pom文件,该 pom包含所有的公共的依赖关系,我们称其为其他子项目 pom的父pom 。这样其他子项目pom中也不用在声明需要用到的依赖,会自动继承父pom的依赖。

        如moduleA和moduleB共同依赖X,则将X抽取出来,同时设置其版本号,这样在升级X依赖时,无需分别对moduleA和moduleB模块中的依赖X进行升级,避免太多模块引用X依赖时忘记升级造成jar包冲突的情况,

        

   (3)dependencyManagement和dependencies的区别:
      dependencies:某个依赖在父pom中声明了,即使在子pom中没有声明该依赖,那么子项目仍然会从父项目中继承该依赖。如果子pom中声明了版本号,那么会覆盖父pom中的版本号。
      dependencyManagement:
        用于集中管理项目中所有模块的依赖关系。它通常位于父模块的 pom.xml 文件中。
        dependencyManagement 只是声明依赖,并不实现引入,只是为子模块提供一个声明性的依赖版本控制机制。
        子模块可以继承父模块中 dependencyManagement 中指定的依赖关系,子pom如果不显示声明依赖,是不会从父项目中继承下来的。
        子pom声明时若没有指定具体版本号,那么version和scope都读取自父pom;如果子pom声明了版本号的话,则会覆盖掉父项目的版本号。

 

十、Maven Wrapper

  1. 含义:用于管理Maven版本的工具,它允许开发者在没有全局安装Maven的情况下,使用指定的Maven版本构建和运行项目
  2. 安装Maven Wrapper后的项目目录结构

 

    

 

 

  3. mvnw命令执行格式

    ./mvnw clean package(添加./是因为当前目录通常不在系统的可执行文件路径中,通过./显示指定当前目录路径)

 

 

 

posted @   sTruth  阅读(22)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示