Maven

作者: 今有所思 | 来源:发表于2018-08-15 11:04 被阅读15次

1. 项目构件和依赖管理

Apache Maven 是一种创新的软件项目管理工具,提供了一个项目对象模型(POM)文件的新概念来管理项目的构建,相关性和文档。最强大的功能就是能够自动下载项目依赖库。

pom.xml是Maven的核心配置文件,pom称为Project Object Model(项目对象模型),它用于描述整个Maven项目,所以也称为Maven描述文件。

  • 约定(惯例)优先原则
    • 标准的目录结构
    • 项目描述符,pom.xml
  • 三方依赖管理
  • 提供了一致的项目构建管理方式
  • 插件式的架构,大量的可重用插件
  • 很方便地集成IDE
  • 开源项目使用Maven

2. 仓库

在Maven的术语中,仓库是这样一个地方或者说是目录,其中存储有项目jar包、库、插件或者任何其他项目指定组件,并且易于被Maven使用。

Maven仓库有三种类型:

  • 本地仓库(local):Maven本地仓库是你电脑上的某个目录地址, 它会在你第一次运行maven任意命令时创建。
  • 远程仓库(remote):开发者自己定制的包含库或者其他项目jar包的仓库
    • 中央仓库(central):Maven中央仓库是由Maven社区提供的仓库,包含大量的常用库。
    • 私服:为了节省带宽和时间,在局域网架设私有的仓库服务器,用其代理所有外部的远程仓库,内部的项目还能部署到私服上供其他项目使用。
    • 其他公共库
      Maven的依赖库查询顺序更改为:
  1. 在 Maven 本地资源库中搜索,如果没有找到,进入第 2 步,否则退出。
  2. 在 Maven 中央存储库搜索,如果没有找到,进入第 3 步,否则退出。
  3. 在 java . net Maven的远程存储库搜索,如果没有找到,提示错误信息,否则退出。

3. pom.xml

Maven 工程结构和内容被定义在一个 xml 文件中,即pom.xml,是 Project Object Model (POM) 的简称,此文件是整个 Maven 系统的基础组件。

<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.xrq.withmaven</groupId>
  <artifactId>withmaven</artifactId>
  <version>0.0.1-SNAPSHOT</version>
</project>
<dependencies>
    <dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.14</version>
    </dependency>
</dependencies>
  1. modelVersion
    指定了当前Maven模型的版本号,对于Maven2和Maven3来说,它只能是4.0.0。

  2. groupId
    顾名思义,这个应该是公司名或是组织名。一般来说groupId是由三个部分组成,每个部分之间以"."分隔,第一部分是项目用途,比如用于商业的就是"com",用于非营利性组织的就是"org";第二部分是公司名,比如"alibaba";第三部分是你的项目名。

  3. artifactId
    可以认为是Maven构建的项目名,比如你的项目中有子项目,就可以使用"项目名-子项目名"的命名方式。

  4. version
    版本号,SNAPSHOT意为快照,说明该项目还在开发中,是不稳定的版本。groupId、artifactId、version三个元素生成了一个Maven项目的基本坐标。

  5. scope
    依赖范围,用来控制依赖和编译,测试,运行的classpath的关系. 主要的是三种依赖关系如下:

    1. compile: 默认编译依赖范围。对于编译,测试,运行三种classpath都有效
    2. test:测试依赖范围。只对于测试classpath有效
    3. provided:已提供依赖范围。对于编译,测试的classpath都有效,但对于运行无效。因为由容器已经提供,例如servlet-api
    4. runtime:运行时提供。例如:jdbc驱动

在上面的这些元素之外,还有一些元素,同样罗列一下:

  1. packing
    项目打包的类型,可以使jar、war、rar、ear、pom,默认是jar

  2. dependencies和dependency
    前者包含后者。前面说了,Maven的一个重要作用就是统一管理jar包,为了一个项目可以build或运行,项目中不可避免的,会依赖很多其他的jar包,在Maven中,这些依赖就被称为dependency。

继承或覆盖

可继承项

  • 坐标属性
  • 依赖配置
  • 插件配置
  • 一般性信息,如开发者信息

依赖传递、依赖排除

Super POM

  • 所有的Maven项目的POM都继承Super POM
  • 是Maven的组成部分
  • 超级POM定义了一组被所有项目共享的默认配置
依赖传递

A项目依赖B,B项目依赖C,此时C项目就会传递到A项目中。

依赖排除

如果此时,A项目依赖B项目,无需依赖C项目,那么需要把自动传递的依赖排除掉,通过<exclusions>标签实现。

依赖调节原则

这个是maven解决传递依赖时jar包冲突问题的方法,maven会先根据第一原则进行选择,第一原则不成,则按第二原则处理。

(1)第一原则:路径近者优先原则

A-->B-->C-->D-->X(1.6)  
E-->D-->X(2.0)  

使用X(2.0),因为其路径更近

(2)第二原则:第一声明者优先原则。就是如果路径相同,maven 默认配置在前面的优先使用

A-->B --> X(1.6)  
C-->D--> X(2.0)

这样就是路径相同,那么如果A在前面,C在后面,则使用X(1.6)

4. 构建生命周期

一个构建生命周期是一组精心组织的有序的阶段
每一个阶段执行预先定义的“动作”

  1. 编译
  2. 打包
  3. 部署
  4. ...

这些“动作”会根据项目的类型进行选择

Maven拥有三套相互独立的生命周期,它们分别为clean、default和site。clean生命周期的目的是清理项目,default生命周期的目的是构建项目,而site生命周期的目的是建立项目站点。

每个生命周期包含一些阶段,这些阶段是有顺序的,并且后面的阶段依赖于前面的阶段,用户和maven最直接的交互方式就是调用这些生命周期阶段。

较之于生命周期阶段的前后依赖关系,三套生命周期本身是相互独立的,用户可以仅仅调用clean生命周期的某个阶段,或者仅仅调用default生命周期的某个阶段,而不会对其他生命周期产生任何影响。

5. 命令

需要在pom.xml所在目录中执行以下命令。

mvn compile(mvn compile -U 强制更新)

完成编译操作,执行完毕后,会生成target目录,该目录中存放了编译后的字节码文件。

-U 该参数能强制让Maven检查所有SNAPSHOT依赖更新,确保集成基于最新的状态,如果没有该参数,Maven默认以天为单位检查更新,而持续集成的频率应该比这高很多。

mvn clean

执行完毕后,会将target目录删除。

mvn test

完成单元测试操作,执行完毕后,会在target目录中生成三个文件夹:surefire、surefire-reports(测试报告)、test-classes(测试的字节码文件)。

mvn package

完成打包操作,执行完毕后,会在target目录中生成一个文件,该文件可能是jar、war。

mvn install

完成将打好的jar包安装到本地仓库的操作,执行完毕后,会在本地仓库中出现安装后的jar包,方便其他工程引用。

mvn clean compile命令

组合指令,先执行clean,再执行compile,通常应用于上线前执行,清除测试类。

mvn clean test命令

组合指令,先执行clean,再执行test,通常应用于测试环节。

mvn clean package命令

组合指令,先执行clean,再执行package,将项目打包,通常应用于发布前。
执行过程:

  1. 清理————清空环境
  2. 编译————编译源码
  3. 测试————测试源码
  4. 打包————将编译的非测试类打包

mvn clean install命令

cmd 中录入 mvn clean install 查看仓库,当前项目被发布到仓库中,组合指令,先执行clean,再执行install,将项目打包,通常应用于发布前。

执行过程:

  1. 清理————清空环境
  2. 编译————编译源码
  3. 测试————测试源码
  4. 打包————将编译的非测试类打包
  5. 部署————将打好的包发布到资源仓库中

不要忘了clean:clean能够保证上一次的构建的输出不会影响到本次构建

指令 作用
编译:mvn compile src/main/java目录java源码编译生成class (target目录下)
测试:mvn test src/test/java 目录编译
清理:mvn clean 删除target目录,也就是将class文件等删除
打包:mvn package 生成压缩文件:java项目#jar包;web项目#war包,也是放在target目录下
安装:mvn install 将压缩文件(jar或者war)上传到本地仓库
部署 发布:mvn deploy 将压缩文件上传私服

package/install/deploy区别

  • package命令完成了项目编译、单元测试、打包功能,但没有把打好的可执行jar包(war包或其它形式的包)布署到本地maven仓库和远程maven私服仓库;

  • install命令完成了项目编译、单元测试、打包功能,同时把打好的可执行jar包(war包或其它形式的包)布署到本地maven仓库,但没有布署到远程maven私服仓库;

  • deploy命令完成了项目编译、单元测试、打包功能,同时把打好的可执行jar包(war包或其它形式的包)布署到本地maven仓库和远程maven私服仓库。

6. maven使用中的常见问题

在maven多模块项目中,内部模块之间常常存在一些互相依赖,假设模块B依赖模块A,我修改了A,增加了一些功能,然后从B中调用这些功能却调用不了,这是什么原因?

修改完A之后并没有将其install或者deploy,所以B依赖的还是修改之前的A,然后B就无法体现A中功能的变更,综上,在开发maven项目时要养成一个好习惯,修改完一个模块之后立即将其install或者deploy,然后再去开发下一个模块。

相关文章

网友评论

      本文标题:Maven

      本文链接:https://www.haomeiwen.com/subject/zhiibftx.html