Java学习笔记——Maven

在JQF的安装过程中,频繁使用了mvn相关的命令,这里留存一些maven的相关笔记,源于廖雪峰Java教程,方便查阅

使用背景

为了保证一个项目A的运行,需要在运行时导入他所需要的所有依赖,假设他依赖于B,那么就有两种解决办法

  • 将B项目打包成jar包,导入到A中,每次下载A,同时也会下载A中包含的B
  • 给A增添使用文档,如果要使用A,就必须由使用者自己再去下载B

第一种方法会造成A包特大,而且如果之前已经有B包在电脑中,这样会重复下载,造成不必要的空间浪费。第二种会增加使用者的工作量,繁琐。在此背景下,出现了Apache Maven,其核心功能是合理叙述项目间的依赖关系,通俗点讲,就是通过pom.xml文件的配置获取jar包。

项目内容

Maven使用pom.xml定义项目内容,有其固定的目录结构,这个结构是自动生成的,不需要自己手动编辑。Maven使用三个变量定位唯一一个依赖,groupId, artifactId, version。声明了一个依赖,Maven就会自动下载这个依赖,并把这个依赖导入Windows的环境变量classpath,之前有博客,写过这个classpath是可以通过IDE设置的.

依赖管理

如果我们的项目依赖 B包,B包的运行又依赖于 C包。在声明的时候,只需要声明依赖B包,C包的依赖会由maven检测,然后自动配置。下面的例子,这个被声明的包,实际上要依赖二三十个包…

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <version>1.4.2.RELEASE</version>
</dependency>

依赖关系

Maven中定义了四种依赖关系

scope说明示例
compile编译时需要用到该jar包(默认)commons-logging
test编译Test时需要用到该jar包junit
runtime编译时不需要,但运行时需要用到mysql
provided编译时需要用到,但运行时由JDK或某个服务器提供servlet-api

其中compile依赖关系,是默认的,其他依赖关系的声明需要用<scope>标签,演示如下:

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.48</version>
    <scope>runtime</scope>
</dependency>

国内镜像

又到了从国外服务器(repo1.maven.org)下载的时候了…被docker支配的恐惧又出现了…感谢阿里爸爸的国内镜像仓库救我小命。

Windows环境下

在用户主目录下,进入.m2目录,创建一个settings.xml配置文件内容如下:

<settings>
    <mirrors>
        <mirror>
            <id>aliyun</id>
            <name>aliyun</name>
            <mirrorOf>central</mirrorOf>
            <!-- 国内推荐阿里云的Maven镜像 -->
            <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
        </mirror>
    </mirrors>
</settings>

Linux环境下

运行下面的命令,这会在用户目录下生成一个./m2目录,刚刚安装完的Maven是没有这个目录的。

在这个隐藏目录之下,新建文件settings.xml,之后流程同上。

第三方插件

如果我们要引用一个第三方组件,比如okhttp,如何确切地获得它的groupIdartifactIdversion

方法是通过search.maven.org搜索关键字,找到对应的组件后,直接复制

构建流程

lifeCycle

Maven的生命周期由一系列阶段(phase)构成

内置生命周期

default

包含以下phase

  • validate
  • initialize
  • generate-sources
  • process-sources
  • generate-resources
  • process-resources
  • compile
  • process-classes
  • generate-test-sources
  • process-test-sources
  • generate-test-resources
  • process-test-resources
  • test-compile
  • process-test-classes
  • test
  • prepare-package
  • package
  • pre-integration-test
  • integration-test
  • post-integration-test
  • verify
  • install
  • deploy
mvn pakage # 执行default生命周期,运行至package为止
mvn compile # 执行default生命周期,运行至compile为止

clean

包含以下phase

  • pre-clean
  • clean (注意这个clean不是lifecycle而是phase)
  • post-clean

Phase

常用开发命令

命令解释
mvn clean清理所有生成的class和jar
mvn clean compile先清理,再执行到compile
mvn clean test先清理,再执行到test,因为执行test前必须执行compile,所以这里不必指定compile
mvn clean package先清理,再执行到package

常用phase

  • clean:清理
  • compile:编译
  • test:运行测试
  • package:打包

Goal

执行一个phase又会触发一个或多个goal:

执行的Phase对应执行的Goal
compilecompiler:compile
testcompiler:testCompile surefile:test

goal的命名总是abc:xyz这种形式。

可以类比:

  • lifecycle相当于Java的package,它包含一个或多个phase;
  • phase相当于Java的class,它包含一个或多个goal;
  • goal相当于class的method,它其实才是真正干活的。

使用插件

实际上,执行每个phase,都是通过某个插件(plugin)来执行的,Maven本身其实并不知道如何执行compile,它只是负责找到对应的compiler插件,然后执行默认的compiler:compile这个goal来完成编译。

所以,使用Maven,实际上就是配置好需要使用的插件,然后通过phase调用它们。下面是常用标准插件。

插件名称对应执行的phase
cleanclean
compilercompile
surefiretest
jarpackage

也可以自定义插件,如果要使用还需要在pom.xml中声明,具体内容应该暂时用不到,用到的时候上网再找吧。关于插件使用与自定义,有Maven的官方文档可供查阅。

模块管理

Maven可以对工程中的模块进行管理,对各个模块中的pom.xml文件中的相同的部分,可以提取出来作为parent的pom.xml文件,放在与各个模块并列的parent文件夹下,使用的时候需要定义

 <parent>
	<groupId>com.itranswarp.learnjava</groupId>
	<artifactId>parent</artifactId>
	<version>1.0</version>
	<relativePath>../parent/pom.xml</relativePath>
</parent>

而模块之间的依赖关系也可以通过pom.xml文件进行声明

    <dependencies>
        <dependency>
            <groupId>com.itranswarp.learnjava</groupId>
            <artifactId>module-b</artifactId>
            <version>1.0</version>
        </dependency>
    </dependencies>

在根目录下需要由一个pom.xml文件进行统一编译,对于各个包含的模块需要声明包含,还需要声明自己的身份。

<modelVersion>4.0.0</modelVersion>
<groupId>com.itranswarp.learnjava</groupId>
<artifactId>build</artifactId>
<version>1.0</version>
<packaging>pom</packaging>
<name>build</name>

<modules>
    <module>parent</module>
    <module>module-a</module>
    <module>module-b</module>
    <module>module-c</module>
</modules>

使用mvnw

全称为Maven Wrapper,提供独立的、指定版本的Maven使用。

mvn -N io.takari:maven:0.7.6:wrapper -Dmaven=3.3.3

这个命令安装了0.7.6版本的Maven Wrapper,并安装了3.3.3版本的Maven,安装过后,按照使用mvn命令的语法使用mvnw命令就可以使用与项目关联的Maven。

在Linux或macOS下运行时需要加上./

./mvnw clean package

其他

Xftp 显示主机中的隐藏文件与隐藏文件夹

工具 - 选项 - 常规 - 勾选“显示隐藏的文件”