maven实战

maven 简介

Apache Maven,是一个软件(特别是Java软件)项目管理及自动构建工具,由Apache软件基金会所提供。基于项目对象模型(缩写:POM)概念,Maven利用一个中央信息片断能管理一个项目的构建、报告和文档等步骤。—来自维基百科

Maven 是基于项目对象模型(POM),可以通过一小段描述信息来管理项目的构建、报告和文档的软件项目管理工具。

Maven是一款强大的自动化构建工具,覆盖了编译、测试、运行、清理、打包和部署等各个项目构建的周期。它提供了一个仓库的概念,帮助统一的管理第三方的jar包,最大可能避免由于环境配置不同所产生的不同环境无法运行的情况。

maven 环境搭建

Maven 的安装:

文件结构:

  • bin 目录:包含mvn的运行脚本。其中 m2.conf 是一个配置文件。
  • boot 目录:包含了一个类加载器的框架plexus-classworlds-2.5.2.jar,maven使用它来加载自己的类库。
  • conf 目录:包含了一些配置文件,例如常用的 settings.xml。
  • lib 目录:包含了 Maven 运行时所用到的所有类库,除了 Maven自身的,还包含了一些第三方依赖的类库。

maven helloWorld程序

直接使用Idea进行创建,过程如下:

  • 创建 maven 项目

  • 选择 GroupId 和 ArtifactId

  • 确定项目名称及保存地址

查看并修改 pom.xml 内容为:

<?xml version="1.0" encoding="UTF-8"?>
<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.maventest</groupId>
    <artifactId>maven.helloworld</artifactId>
    <version>1.0-SNAPSHOT</version>
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.10</version>
        </dependency>
    </dependencies>

</project>
  • 构建结构目录为:

// HelloWorld.java 文件为:
package com.maventest.helloworld;

public class HelloWorld {
    public String sayHello(){
        return "Hello World!";
    }
}

// HelloWorldTest.java 文件为:
package com.maventest.helloworld;

import org.junit.*;
import org.junit.Assert.*;

public class HelloWorldTest {
    @Test
    public void testHello(){
        Assert.assertEquals("Hello World!", new HelloWorld().sayHello());
    }
}

在 terminal 中依次输入如下命令,并观察输出:

  • mvn compile
  • mvn test
  • mvn package

maven 核心知识

maven 常用命令

compile: 编译
test: 测试
package: 打包
clean: 删除target
install: 安装jar包到本地仓库

maven 自动建立目录骨架

archetype插件:用于创建符合 maven 规定的目录骨架。

创建目录的两种方式:

  • mav archetype:generate
  • mvn archetype:generate -DgroupId=com.imooc.maven04 -DartifactId=maven04-demo -Dversion=1.0.0SNAPSHOT -Dpackage=com.imooc.maven04.demo

maven 中的坐标和仓库

构件:在 maven 中,任何一个插件、依赖以及构件的输出都可以称为构件。

坐标:所有构件均通过构件作为其唯一标识。包括(groupId, artifactId, version)

例如:

  • groupId:com.imooc.maven01,其中 com.imooc 为公司名的反写,maven01 为项目名。
  • artifactId: maven01-model,其中 maven01 为项目名,model 为该项目的模块名。
  • version: 0.0.1SNAPSHOT,为项目所构件的版本

仓库:用来管理项目的依赖。仓库主要分为 本地仓库远程仓库两种。依赖会先在本地仓库中进行查找,如果查找不到就会在远程仓库进行查找,在远程仓库中能查找到则下载到本地仓库中去,不能查找到则会报错。

maven 全球中央仓库地址:https://repo.maven.apache.org/maven2

修改镜像仓库: 修改 maven/conf/settings.xml 文件。修改下面的内容为:

<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>
    <mirrorOf>central</mirrorOf>
    <name>central mirror in china</name>
    <url>http://maven.net.cn/content/groups/public</url>
</mirror>
    -->
</mirrors>

仓库位置:${M2_HOME}/conf/settings.xml 文件。

同时将 settings.xml 文件复制一份到 ${user.home}/.m2/settings.xml 文件夹下。

maven的配置文件settings.xml存在于两个地方:

1.安装的地方:${M2_HOME}/conf/settings.xml

2.用户的目录:${user.home}/.m2/settings.xml

前者又被叫做全局配置,对操作系统的所有使用者生效;后者被称为用户配置,只对当前操作系统的使用者生效。如果两者都存在,它们的内容将被合并,并且用户范围的 settings.xml 会覆盖全局的 settings.xml。

Maven安装后,用户目录下不会自动生成 settings.xml,只有全局配置文件。如果需要创建用户范围的 settings.xml,可以将安装路径下的 settings 复制到目录${user.home}/.m2/。Maven默认的settings.xml是一个包含了注释和例子的模板,可以快速的修改它来达到你的要求。

全局配置一旦更改,所有的用户都会受到影响,而且如果 maven 进行升级,所有的配置都会被清除,所以要提前复制和备份 ${M2_HOME}/conf/settings.xml文件,一般情况下不推荐配置全局的 settings.xml。

将复制后的 ${user.home}/.m2/settings.xml 修改下面的内容为:

<localRepository>/path/to/local/repo</localRepository>

即可将仓库指定到 /path/to/local/repo 路径下。

maven 的生命周期和插件

完整的项目构建过程包括:清理、编译、测试、打包、集成测试、验证和部署。

  • clean: 清理项目
    • pre-clean: 执行清理前的工作
    • clean: 清理上一次构建生成的所有文件
    • post-clean: 执行清理后的文件
  • default: 构建项目(最核心)
    • compile:
    • test:
    • package:
    • install:
  • site: 生成项目站点
    • pre-site: 生成项目站点前要完成工作
    • site: 生成项目的站点文档
    • post-site: 在生成项目站点后要完成的工作
    • site-deploy: 发布生成站点到服务器上

maven 插件:https://maven.apache.org/plugins/index.html 目录下都是 maven 的插件。

例如:使用 source 插件,该插件可以将项目的源码进行打包。

在项目的 pom.xml 文件中,添加一下内容:

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugin</groupId>
            <artifactId>maven-source-plugin</artifactID>
            <version>2,4</version>
            <executions>
                <phase>package</phase>
                <goals>
                    <goal>jar-no-fork</goal>
                </goals>
            </executions>
        </plugin>
    </plugins>
</build>

例如:执行 package 命令时,会默认将前面的 compile, test 命令自动执行。

maven 中 pom.xml 解析

pom,xml 文件是用于项目描述,组织管理,依赖管理和构建信息。

根项目元素:

<project xmlns:'pom的约束信息'>
    <!--制定了当前pom的版本-->
    <modelVersion></modelVersion>

    <groupId>反写的公司网址+项目名</groupId>
    <artifactId>项目名+模块名</artifactId>
    <!--第一个0表示大版本号
        第二个0表示分支版本号
        第三个0表示小版本号
        0.01
        snapshot快照
        alpha内部测试
        beta公测
        release稳定
        GA正式发布
    -->
    <version></version>
    <!--默认是jar
        war zip pom
    -->
    <packaging></packaging>

    <!--项目描述名,产生文档时会使用-->
    <name></name>
    <!--项目的地址-->
    <url></url>
    <!--项目的描述-->
    <description></description>
    <!--开发人员信息-->
    <developers></developers>
    <!--许可证件-->
    <licenses></licenses>
    <!--组织信息-->
    <organization></organization>

    <!--依赖类-->
    <dependencies>
        <dependency>
            <groupId></groupId>
            <artifactId></artifactId>
            <veriosn></version>
            <type></type>
            <!--scope指定依赖的范围
                例如junit指定的test, 指的是只在 test 测试过程有用
            -->
            <scope>test<scope>
            <!-- 设置依赖是否可选,默认是 false-->
            <optional></optional>
            <!--排除依赖传递列表-->
            <exclusions>
                <exclusion>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

    <!--依赖的管理,并不会引入依赖-->
    <dependencyManagement>
        <dependencies>
            <dependency>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <!--build 对相应的构建行为提供相应的支持-->
    <build>
        <!--插件列表-->
        <plugins>
            <plugin>
                <groupId></groupId>
                <artifactId></artifactId>
                <veriosn></version>
            </plugin>
        </plugins>
    </build>
    <!-- 对父依赖的继承-->
    <parent></parent>
    <!-- 指定多个模块。一起编译-->
    <modules>
        <module></module>
    </modules>
</project>

maven 依赖范围

scope 指定6中依赖范围:Dependency Scope

  • compile: 默认范围
  • provided: 编译测试时有效
  • runtime: 测试和运行时有效
  • test: 测试时有效
  • system: 本机系统相关:编译和测试时有效
  • import: 导入的范围

maven 依赖传递

假如 A 依赖于 B,B 依赖于 C。则在 A 引入 B 的依赖时,会将 C 的依赖也引入进来,要想 A 至依赖于 B,可以通过 exclusions 将 C 排除在外:

<exclusions>
    <exclusion>
        <groupID></groupID>
        <artifactId></artifactId>
        <version></veriosn>
    </exclusion>
</exclusions>

依赖冲突

1 短路优先

A -> B -> C -> X(jar)
A -> D -> X(jar)

假如,A 依赖的 B,D 所依赖的 X 的版本不同,根据短路优先原则,A 会依赖 D 所依赖的 X(jar)

2 路径相同时,先声明先优先

maven 聚合和继承

<parent></parent>
<packaging>pom</packaging>
<modules>
    <module></module>
</modules>

maven 构建web项目

参考资料