MAVEN使用学习

MAVEN

maven编译过程

编译主代码

  • mvn clean compile

    clean 告诉maven清理输出目录target(target目录为maven默认构建的所有输出都在target目录中)

    comile 告诉maven编译项目主代码

依次执行的过程为

clean,

resources项目主资源处理(如果没有定义项目资源,会跳过)

compile编译主代码,将项目主代码编译到targe/classes目录

执行测试代码

  • mvn clean test
    1. clean
    2. resources
    3. compile
    4. testResources
    5. testCompile
    6. test

打包和运行

  • mvn clean package

    1. clean
    2. resources
    3. compile
    4. testResources
    5. testCompile
    6. test
    7. jar,打包插件
  • mvn clean install

    如果是maven项目要想直接在pom.xml文件中引入该jar包,则需要把该jar包安装在本地仓库中

    • 在执行打包之前,依次执行了编译,测试,打包

    这条命令会将jar包打包并安装在本地的mvn仓库中

maven构成–坐标

  • 基础坐标
    1. groupId
    2. artifactId
    3. version

maven依赖

maven项目中需要使用其他依赖时,需要在pom.xml中配置<dependency> 元素,作为依赖声明。

这样在编写项目时就可以使用依赖了,并且会在打包时自动将依赖的jar包打包到项目中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<project>
<dependencies>
...
<dependency>
<groupId>...</groupId>
<artifactId>...</artifactId>
<version>...</version>
<type>...</type>
<scope>...</scope>
<optional>...</optional>
<exclusions>
<exclusion>
...
</exclusion>
</exclusions>
</dependency>
...
</dependencies>
</project>
  • 依赖范围

    1. 编译classpath:编译主代码有效
    2. 测试classpath:编译、运行测试代码有效
    3. 运行classpath:项目运行时有效
  • maven的依赖范围:

    1. compile
    2. test
    3. provided
    4. runtime
    5. system
  • 依赖传递

  • 依赖优先

  • 可选依赖

  • 排除依赖

  • 归类依赖

    当依赖的多个模块版本相同时,为了方便统一,所以用properties 元素定义maven属性,

    通过使用${xxx}替换掉实际值,将所有依赖的版本值都使用这一引用值表示。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    <project>
    ....
    <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <springframework.version>4.3.2.RELEASE</springframework.version>
    </properties>

    <dependencies>
    <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>${springframework.version}</version>
    </dependency>
    <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-beans</artifactId>
    <version>${springframework.version}</version>
    </dependency>
    <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>${springframework.version}</version>
    </dependency>
    <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
    <version>${springframework.version}</version>
    </dependency>
    </dependencies>
    ...
    </project>
  • 查看已解析依赖

    mvn dependency:list

  • 查看依赖树

    mvn dependency:tree

  • 分析依赖书

    mvn dependency:analyze

    分析结果有两部分:

    • Used undeclared dependencies found:表示为项目中使用到的,但是没有显示声明的依赖(可能为传递依赖)
    • Unused declared dependencies found:表示项目中未使用的,但显示声明的依赖,没有使用是指没有在编译主代码和测试代码中使用的依赖,也有可能在项目运行中会使用

maven仓库 –从仓库解析依赖的机制

仓库分类:

  1. 本地仓库
  2. 远程仓库
    1. 中央仓库
    2. 私服

远程仓库配置

  1. 配置

    默认的中央仓库如果无法满足项目需求,可能需要的构件在其他的远程仓库,如JBoss Maven仓库,可以在pom中配置该仓库。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    <repositories>
    ....
    <repository>
    <id>jboss</id>
    <name>JBoss Repository</name>
    <url>https://repository.jboss.com/maven2/</url>
    <layout>default</layout>
    <snapshots>
    <enabled>false</enabled>
    </snapshots>
    <releases>
    <enabled>true</enabled>
    </releases>
    </repository>
    ....
    </repositories>
  2. 解释

    • id要唯一

    • release的enabled 为true,表示开始JBoss仓库的发布版本下载支持,从上面的配置来看,maven只从JBoss仓库中下载发布版的构件而不会下载snapshot快照版本。

    • 对于releases和snapshots来说,除了enabled还包含两个子元素updataPolicy和checksumPolicy

      1
      2
      3
      4
      5
      <releases>
      <enabled>true</enabled>
      <updataPolicy>daily</updataPolicy>
      <checksumPolicy>warn</checksumPolicy>
      </releases>
      • updataPolicy:配置maven从远程仓库检查更新的频率,对同一个版本(如:log4j.1.2.15.jar)的构件如果发现有更新(如:对log4j.1.2.15.jar进行了内容修复但是版本都不变)会下载最新的。默认daily-maven每天检查一次

      never-从不检查;always-每次构件都要检查更新;interval:X -每隔X分钟检查一次更新(X为整数)

      • 当然:用户可以使用参数-U,强制检查更新,使用参数后,maven就会忽略updatePolicy的配置。
      • checksumPolicy:用来配置Maven检查校验和文件失败后的策略。构件被部署到maven仓库中时会同时部署对应的校验和文件,maven会验证校验和文件以确定下载的构件是否完整,如果校验失败,怎么办?策略有3中:(默认值)warn-maven会执行构建时输出警告信息;fail-maven遇到校验和错处就让构建失败;ignore-使maven完全忽略校验和错误。

    部署当前maven项目到远程仓库

    1. 需求

      • 私服的一个作用是部署公司内部生成的构件以及一些无法从外部仓库获取的构件。那么如何把maven项目部署到私服上或者其他的远程服务器上呢?
    2. 操作步骤

      步骤-1配置pom.xml
      需要编写pom.xml文件,配置distributionManagement元素。

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      <distributionManagement>
      <repository>
      <id>proj-releases</id>
      <name>Proj Release Repository</name>
      <url>http://192.168.1.100/content/repositories/proj-releases</url>
      </repository>
      <snapshotRepository>
      <id>proj-snapshots</id>
      <name>Proj Snapshot Repository</name>
      <url>http://192.168.1.100/content/repositories/proj-snapshots</url>
      </snapshotRepository>
      </distributionManagement>
      • distributionManagement包含repository和snapshotRepository子元素,前者表示发布版本构件的仓库,后者表示快照版本的仓库。
      • id为远程仓库的唯一标识,name是为了方便人阅读,url表示该仓库的地址。

      步骤-2配置settings.xml

      • 往仓库部署构件往往需要认证,配置方式如上面所讲,只需要配置settings.xml中的server元素。同时其id要与仓库id匹配。不论部署还是下载构件,当需要认证时配置方式一样。

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        <settings>
        ...
        <servers>
        <server>
        <id>my-proj</id>
        <username>repo-user</username>
        <password>repo-pwd</password>
        </server>
        </servers>
        ...
        </settings>

        这里的id=my-proj一定要和pom.xml中仓库的id一致,这是它们之间唯一的联系。

        settings.xml的servers中就是用来配服务器授权信息的,当然不仅可以配置仓库服务器认证信息,还可以配置其它的比如tomcat服务器授权信息也可以在这里配置。

      步骤-3使用部署命令

      • 在命令行运行 mvn clean deploy。Maven就会将项目构建输出的构件部署到配置对应的远程仓库,如果项目版本是快照版本就部署到快照版本仓库地址,同理发布版本仓库地址。

从仓库解析依赖的机制(重要)

maven是根据怎样的规则从仓库解析并使用依赖的构件的呢?

  • 1.解析构件步骤(插件、依赖的解析)

    1. 当依赖范围是system时候,Maven直接从本地文件解析构件。

    2. 根据依赖坐标计算仓库路径后,先从本地仓库寻找构件,如果发现则解析成功。

    3. 本地仓库没找到,如果依赖版本(version)是发布版构件,即1.2,2.3等,则遍历远程仓库,发现后下载并解析使用。

    4. 如果version是SNAPSHOT版,如:2.1-SNAPSHOT,则基于更新策略(updatepolicy)读取所有远程仓库的元数据groupId/artifactId/version/maven-metadata.xml,将其与本地仓库的对应元数据合并后,得到最新快照版本的值,然后基于该值检查本地仓库,或者从远程仓库下载。(如果最新版还是之前的值就不需要去远程仓库下载了)。

      注意:这一步因为updatepolicy的原因,可能要求本机能连接到远程仓库(远程仓库可以是私服或者中央仓库,一般只有自己的项目会使用SNAPSHOT,所以大多数是私服

    5. 如果最后解析得到构件版本是时间戳格式的快照,如1.4.1-20161121.121432-121则复制其时间戳格式的文件至非时间戳格式,如SNAPSHOT,并使用该时间戳格式的构件。

    6. 当依赖的version值为RELEASE时(不建议),Maven会基于updatepolicy策略读取远程仓库的元数据groupId/artifactId/maven-metadata.xml,将其与本地仓库相对应元数据合并后,计算出最新版本的RELEASE值(稳定版),然后基于这个值检查本地和远程仓库,步骤如2和3。

      注意:存在潜在问题,如某个依赖的1.1版本与1.2版本可能发生一些接口变化,从而导致当前Maven项目构建失败,所以依赖的版本最好确定

      注:第4步骤在6.2、6.3节有详解

  • 2.解析进一步说明

镜像

  • 什么是镜像

    如果仓库x可以提供仓库y存储的所有内容,那么就可以认为x是y的一个镜像mirror

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    <settings>
    <mirrors>
    <!-- mirror
    | Specifies a repository mirror site to use instead of a given repository. The repository that
    | this mirror serves has an ID that matches the mirrorOf element of this mirror. IDs are used
    | for inheritance and direct lookup purposes, and must be unique across the set of mirrors.
    | -->
    <mirror>
    <id>maven.net.cn</id>
    <name>one of the central mirrors in China</name>
    <url>http://maven.net.cn/content/groups/public/</url>
    <mirrorOf>central</mirrorOf>
    </mirror>
    </mirrors>
    </settings>
    • 上面的配置中,mirrorOf为central,表示该配置为中央仓库的镜像,任何对于中央仓库的请求都会转到该镜像。用户也可以使用该方式,配置其他仓库的镜像。
    • 镜像一般用在私服上,因为私服代理了任何外部的公共仓库,对于组织内容的maven用户来说,使用一个私服地址等于使用所有外部仓库。

maven 生命周期和插件

maven的设计中,实际的任务(如编译源代码)都交给插件来完成,这种设计思想类似于设计模式中的模板方法

模板方法模式:在父类中定义算法的整体结构,子类可以通过实现或者重写父类的方法来控制实际的行为。这样既保证了算法足够的可扩展性,又严格控制算法的整体结构

  • **maven生命周期 **

    1. maven的生命周期抽象类构建的各个步骤,定义了次序,但是么有提供具体实现,由插件 来实现。

    2. maven的生命周期的每个阶段都可以绑定一个或多个插件行为,并且maven的大多数构建步骤绑定了默认的插件

    3. maven生命周期与插件机制的优点:

      一方面,保证了所有maven项目都有一致的构建标准(步骤),

      另一方面,通过默认插件,简化和稳定了实际项目构建

      此外,这个机制还提供了足够的扩展空间,用户可以通过配置现有插件或者自行编写插件来完成自定义构建行为。

  • **三套生命周期 **

    项目构建的生命周期一般包括:项目清理,初始化,编译,测试,打包,集成测试,验证,部署,站点生成等阶段

    • maven简化了构建过程,三套独立的生命周期:clean ,default , site .

    每个生命周期内都有各个阶段,每个阶段都是由次序关系的

    • clean: 清理项目
    • default: 构建项目(核心生命周期)
    • **site: ** 建立项目站点
  • 命令行与生命周期

    • 从命令行执行maven任务,最主要的方式是调用maven生命周期
    • $ mvn clean : 该命令,调用clean生命周期的clean阶段,实际执行的阶段为clean生命周期的pre-clean 和clean阶段
    • $ mvn clean deploy site-deploy:该命令调用clean生命周期的clean阶段、default周期的deploy阶段、site生命周期的site-deploy阶段。实际执行clean生命周期pre-clean,clean
      阶段,default生命周期所有阶段,site生命周期所有阶段。
    • $ mvn clean install所执行的任务
  • 插件目标

    • Maven的核心仅仅定义了抽象生命周期,具体工作由插件完成,对于插件本身,为了能够实现代码复用,它往往能完成多个任务,也就具有多个功能,这些功能聚集在一个插件中,每个功能就叫做一个插件目标。
    • maven-dependency-plugin插件有十多个目标,每个目标对应一个功能,目标有:dependency:analyze、dependency:tree、dependency:list这是一种通用写法,冒号前面是插件前缀,后面是插件目标
  • 插件绑定

    把插件的目标goal,绑定到maven生命周期的某个阶段用于完成实际任务,叫做插件绑定

  • 内置绑定

  • 自定义绑定

    1. 确定插件目标,首先通过查看插件,找到合适的插件目标,(基本上所有的插件都来源于Apache和Codehaus)
    2. 确定生命周期,查看生命周期的各个阶段,找到合适的位置,
    3. 在pom.xml文件中配置,将插件和其目标与 生命周期的阶段相绑定
  • 插件配置

    插件和生命周期绑定后,可以配置插件和插件目标的参数,

    可以在命令行配置,也可以在pom.xml中配置

  • 获取插件信息

    1. 在线获取

    2. 使用maven-help-plugin描述插件获取

      例:mvn help:describe -Dplugin=xxx(想获取信息的插件)

  • 插件解析机制

    与依赖构件一样,插件构件也基于坐标存在与maven仓库中

    • 插件前缀
    • 插件解析版本
    • 插件的groupId

遇到过得问题

mvn com.coveo:fmt-maven-plugin:format -Dmaven.wagon.http.ssl.insecure=true -Dmaven.wagon.http.ssl.allowall=true

mvn com.coveo:fmt-maven-plugin:format 报错,无法获取指定依赖包

1
[ERROR] Failed to execute goal com.coveo:fmt-maven-plugin:2.9:format (default-cli) on project dataflow_preprocess_topic_rest: Execution default-cli of goal com.coveo:fmt-maven-plugin:2.9:format failed: Plugin com.coveo:fmt-maven-plugin:2.9 or one of its dependencies could not be resolved: Failed to collect dependencies at com.coveo:fmt-maven-plugin:jar:2.9 -> com.google.googlejavaformat:google-java-format:jar:1.7 -> com.google.errorprone:javac-shaded:jar:9+181-r4173-1: Failed to read artifact descriptor for com.google.errorprone:javac-shaded:jar:9+181-r4173-1: Could not transfer artifact com.google.errorprone:javac-shaded:pom:9+181-r4173-1 from/to aliyunmaven (https://maven.aliyun.com/repository/public): Authorization failed for https://maven.aliyun.com/repository/public/com/google/errorprone/javac-shaded/9+181-r4173-1/javac-shaded-9+181-r4173-1.pom 403 Forbidden -> [Help 1]

解决:手动下载指定pom后,重新执行
过程: 更换maven源地址等操作并不生效,最终手动下载有错误的pom后,顺利解决

常用的命令

1
2
3
4
5
pom.xml中配置了fmt插件后,手动format代码的命令
mvn com.coveo:fmt-maven-plugin:format

maven打包时跳过单元测试的命令
mvn clean package -Dmaven.test.skip=true
  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!
  • Copyrights © 2022-2023 ligongzhao
  • 访问人数: | 浏览次数:

请我喝杯咖啡吧~

支付宝
微信