一文带你掌握80%的Maven知识点

876 阅读2分钟

一.坐标

Maven坐标相当于一种表示标识,只有为项目提供正确的坐标元素,Maven才会找到相应的jar包或者war包

<groupId>com.jyh</groupId>
<artifactId>garbageadmin</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>

关键字解析:

属性 含义
groupId 定义当前项目属于哪个实际项目,往往一个实际项目包含多个maven项目
artifactId 定义项目中的一个maven模块
version 定义当前项目的版本
packaging 定义项目打包的方式,通常情况下有war,jar
classifier (可选项)用来区分在相同版本下针对不同的环境或者jdk使用的jar包

二.依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <version>2.1.6.RELEASE</version>
    <type>jar</type>          //默认即可
    <scope>compile</scope>
    <optional>true</optional>    //可选项。不推荐使用
    <exclusions>
        <exclusion>
        </exclusion>
    </exclusions>
</dependency>
属性 含义
version 可自定义版本,使用properties元素定义Maven属性,在version使用${}引用Maven属性
type 依赖类型,默认为jar
scope 依赖范围
optional 可选依赖
exclusions 排除传递性依赖,当某个传递性依赖jar会造成当前项目冲突时,就需要通过exclusions排除

传递性依赖

1依赖2,2依赖3,由于Maven依赖传递机制,maven解析会pom文件,所以1无需考虑1依赖什么,1也不会引入多余的传递依赖

可选依赖

项目1依赖项目2,项目2支持3,4两个jar包,但是项目1只需要其中一个,所以3,4就成为可选依赖。这个时候,项目A就需要显示的声明需要依赖的是3或者4

依赖范围

编译classpath、测试classpath、运行classpath

  1. compile,缺省值,适用于所有阶段,会随着项目一起发布
  2. provided,类似compile,期望JDK、容器或使用者会提供这个依赖
  3. runtime,只在运行时使用,适用运行和测试阶段
  4. test,只在测试时使用,用于编译和运行测试代码。不会随项目发布
  5. system,类似provided,需要显式提供包含依赖的jar,Maven不会在Repository中查找它。

自定义maven属性

<properties>
    <java.version>1.8</java.version>
</properties>

三.仓库

Maven仓库分为 本地仓库 与 远程仓库

Maven依赖包寻找顺序:

  1. 先去本地仓库找寻,有的话,直接使用
  2. 本地仓库没有找到的话,会去远程仓库找寻,下载包到本地仓库
  3. 远程仓库没有找到的话,会报错

私服

私服是一种特殊的远程Maven仓库,它是架设在局域网内的仓库服务,私服一般被配置为互联网远程仓库的镜像,供局域网内的Maven用户使用。

当Maven需要下载构件的时候,先向私服请求,如果私服上不存在该构件,则从外部的远程仓库下载,同时缓存在私服之上,然后为Maven下载请求提供下载服务,另外,对于自定义或第三方的jar可以从本地上传到私服,供局域网内其他maven用户使用。

配置远程仓库的三种方式:

1.settings.xml 配置mirror镜像,注意使用镜像作为远程中央仓库,mirrorOf的值应为central ,替换默认的

2.pom.xml 配置远程仓库

<repositories>
    <repository>
        <id>person</id>
        <name>person Repository</name>
        <url>http://localhost:8088/nexus/content/repositories/releases/</url>
        <releases>
            <enabled>true</enabled>
        </releases>
        <snapshots>
            <enabled>false</enabled>
        </snapshots>
    </repository>
</repositories>
  • id :与settings.xml 中mirrorOf的一样,定义仓库的唯一标识
  • url:定义远程仓库的地址
  • snapshot:快照仓库用于保存开发过程中的不稳定版本
  • release:正式仓库则是用来保存稳定的发行版本

配置远程公共仓库无需认证信息,如果远程仓库为项目自己的开发maven库,为提高仓库安全性,需要在settings.xml配置server信息。

<servers>
    <server>
       <id>persion</id>
       <username>admin</username>
       <password>admin123</password>
    </server>
</servers>

这里的关键是id元素,settings.xml中server元素的id必须与pom.xml中需要认证的repository元素的id完全一致。正是这个id将认证信息与仓库配置联系在了一起。

3.把方式2代码放置在settings.xml文件中,定义在profile标签中。此时需要为当前profile配置id的标签。然后需要启用当前配置的profile。启用的方式为:

<profiles>
    <profile>
         <id>dev</id>
         <repositories>       
             <repository>
               ...
             </repository>   
         </repositories>
   </profile>
</profiles>
<activeProfiles>
   <activeProfile>dev</activeProfile>
</activeProfiles>

镜像

仓库A可以提供仓库B存储的所有内容,那么就可以认为A是B的一个镜像

Maven仓库默认在国外,下载速度极慢。一般情况都需要替换maven镜像文件,配置settings.xml文件

mirrorOf的值为central,表示该配置为中央仓库的镜像,任何对于中央仓库的请求都会转至该镜像

<mirror>
    <id>alimaven</id>
    <mirrorOf>central</mirrorOf>
    <name>aliyun maven</name>
    <url>http://maven.aliyun.com/nexus/content/repositories/central/</url>
</mirror>

部署远程私服仓库

项目打包部署到私服仓库,供项目组其他成员使用。pom.xml配置为:

<distributionManagement>
    <repository>
        <id>releases</id>
        <url>http://188.188.188.98:8080/nexus-2.12.0-01/content/repositories/releases/</url>
    </repository>
    <snapshotRepository>
        <id>snapshots</id>
        <url>http://188.188.188.98:8080/nexus-2.12.0-01/content/repositories/snapshots/</url>
    </snapshotRepository>
</distributionManagement>

四.生命周期

Maven有以下三种标准的生命周期:

     clean  清理项目    
   default  构建项目   
      site  建立项目站点
清洁(Clean)生命周期
  • pre-clean 执行一些需要在clean之前完成的工作
  • clean 移除所有上一次构建生成的文件
  • post-clean 执行一些需要在clean之后立刻完成的工作
默认(default)生命周期
生命周期阶段 描述
validate 验证项目是否正确,并且所有必要的信息可用于完成构建过程
initialize 建立初始化状态,例如设置属性
generate-sources 产生任何的源代码包含在编译阶段
process-sources 处理源代码,例如,过滤器值
generate-resources 包含在包中产生的资源
process-resources 复制和处理资源到目标目录,准备打包阶段
compile 编译该项目的源代码
process-classes 从编译生成的文件提交处理,例如:Java类的字节码增强/优化
generate-test-sources 生成任何测试的源代码包含在编译阶段
process-test-sources 处理测试源代码,例如,过滤器任何值
test-compile 编译测试源代码到测试目标目录
process-test-classes 处理测试代码文件编译生成的文件
test 运行测试使用合适的单元测试框架(JUnit)
prepare-package 执行必要的任何操作的实际打包之前准备一个包
package 提取编译后的代码,并在其分发格式打包,如JAR,WAR或EAR文件
pre-integration-test 完成执行集成测试之前所需操作。例如,设置所需的环境
integration-test 处理并在必要时部署软件包到集成测试可以运行的环境
pre-integration-test 完成集成测试已全部执行后所需操作。例如,清理环境
verify 运行任何检查,验证包是有效的,符合质量审核规定
install 将包安装到本地存储库,它可以用作当地其他项目的依赖
deploy 复制最终的包到远程仓库与其他开发者和项目共享
网站(site)生命周期
  • pre-site 执行项目执行需要的完成工作
  • site 生成项目站点文档
  • post-site 执行项目站点之后需要的工作
  • site-deploy 将生成的项目站点发布到服务器
常用命令详解
mvn clean   执行clean生命周期中,运行某个阶段的时候,它之前的所有阶段都会被运行,也就是说,mvn clean 等同于 mvn pre-clean clean 
mvn install  执行default生命周期,代码会被执行编译,测试,打包

五.插件

分为两种,内置绑定 与 自定义绑定

自定义绑定插件是在 pom.xml 中使用 plugins 元素定义的

Maven 实际上是一个依赖插件执行的框架,每个任务实际上是由插件完成。Maven 插件通常被用来:

  • 创建 jar 文件
  • 创建 war 文件
  • 编译代码文件
  • 代码单元测试
  • 创建工程文档
  • 创建工程报告

插件通常提供了一个目标的集合,并且可以使用下面的语法执行:

mvn [plugin-name]:[goal-name]

例如,一个 Java 工程可以使用 maven-compiler-plugin 的 compile-goal 编译,使用以下命令:

mvn compiler:compile

六.聚合

  • 目的:项目现在采用的都是多模块开发,父模块承担聚合模块和统一管理依赖的作用,只需要有pom文件即可,没有src与test目录

  • 必要条件
    父模块pom:1.packaging:pom

    子模块pom:1.modules: 实现聚合的核心,module值为被聚合模块相对于聚合POM的相对路径,每个被聚合模块下还各自包含有pom.xml、src/main/java、src/test/java等内容, 离开聚合POM也能够独立构建

项目A的pom文件:

<?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.example</groupId>
    <artifactId>A</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>
    <modules>
        <module>B</module>
        <module>C</module>
    </modules>
</project>

聚合的依赖传递

子模块的 pom 中, 需要什么依赖就直接引入, 不引入版本号, 依赖会自动从父模块中传递到子模块中. 父工程A的pom文件:

<!-- 定义版本号 -->
<properties>
    <mybatis.version>4.3.7.RELEASE</mybatis.version>
</properties>
<!-- 统一管理依赖 -->
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>${mybatis.version}</version>
        </dependency>
    </dependencies>
</dependencyManagement>

子工程B的pom文件: 子模块使用无需定义版本号

<dependencies>
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
    </dependency>
</dependencies>

打包无需挨个执行,直接在父模块A执行 mvn clean package 命令 B,C就会同时被构建

七.继承

  • 目的:消除重复
  • 必要条件: 父模块pom:1.packaging:pom 子模块pom:1.元素的属性:: 父模块POM的相对路径

父模块的pom文件配置如下:

<?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.example</groupId>
    <artifactId>A</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>
    <!-- 定义版本号 -->
    <properties>
        <mybatis.version>4.3.7.RELEASE</mybatis.version>
    </properties>
    <!-- 统一管理依赖 -->
    <dependencies>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
    </dependencies>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.mybatis</groupId>
                <artifactId>mybatis</artifactId>
                <version>${mybatis.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>
</project>

子模块的pom文件配置如下:

<?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">
    <parent>
        <artifactId>A</artifactId>
        <groupId>com.example</groupId>
        <version>1.0-SNAPSHOT</version>
        <relativePath>../pom.xml</relativePath>    //重点!!!!!!!!!
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>B</artifactId>
    <dependencies>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
        </dependency>
    </dependencies>
</project>

dependencies: 该定义下的依赖,子模块可以共享

dependencyManagement: 该定义下的依赖,子模块不会共享 父模块用dependencyManagement进行管理,这样的好处是子模块可以有选择性的继承,而不需要全部继承。子项目中要引入group Id和atifactId,version和scope继承父模块中的配置