❤️💕💕java的学习指南,从入门到大师篇章。Myblog:http://nsddd.top
[TOC]
Maven是一个Java项目管理和构建工具,它可以定义项目结构、项目依赖,并使用统一的方式进行自动化构建,是Java项目不可缺少的工具。
Maven就是是专门为Java项目打造的管理和构建工具,它的主要功能有:
- 提供了一套标准化的项目结构;
- 不同的ide项目结构不一样,就会导致无法导入到其他的ide
- 提供了一套标准化的构建流程(编译,测试,打包,发布……);
- 提供了一套依赖管理机制。
- 依赖管理就是管理你项目中所依赖的第三方资源(jar包、插件)
Maven是一个Java项目的管理和构建工具:
- Maven使用
pom.xml
定义项目内容,并使用预设的目录结构; - 在Maven中声明一个依赖项可以自动下载并导入classpath;
- Maven使用
groupId
,artifactId
和version
唯一定位一个依赖。
一个使用Maven管理的普通的Java项目,它的目录结构默认如下:
a-maven-project # 项目名称,自己取
├── pom.xml # 配置文件,对核心配置文件
├── src # 存放代码
│ ├── main # 存放源代码
│ │ ├── java # 存放java源代码
│ │ └── resources # 源代码的配置文件目录
│ │ └── webapp # web项目所需要的目录 -- 可以选择不要
│ └── test # 存放测试代码
│ ├── java # 存放java测试源代码
│ └── resources # 测试代码的配置文件目录
└── target # 所有编译、打包生成的文件都放在target目录里
项目的根目录a-maven-project
是项目名,它有一个项目描述文件pom.xml
,存放Java源码的目录是src/main/java
,存放资源文件的目录是src/main/resources
,存放测试源码的目录是src/test/java
,存放测试资源的目录是src/test/resources
,最后,所有编译、打包生成的文件都放在target
目录里。这些就是一个Maven项目的标准目录结构。
我们再来看最关键的一个项目描述文件pom.xml
,它的内容长得像下面:
<project ...>
<modelVersion>4.0.0</modelVersion>
<groupId>com.itranswarp.learnjava</groupId>
<artifactId>hello</artifactId>
<version>1.0</version>
<packaging>jar</packaging>
<properties>
...
</properties>
<dependencies>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
</dependencies>
</project>
其中,groupId
类似于Java的包名,通常是公司或组织名称,artifactId
类似于Java的类名,通常是项目名称,再加上version
,一个Maven工程就是由groupId
,artifactId
和version
作为唯一标识。我们在引用其他第三方库的时候,也是通过这3个变量确定。例如,依赖commons-logging
:
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
使用<dependency>
声明一个依赖后,Maven就会自动下载这个依赖包并把它放到classpath中。
安装好了目录结构:
PS D:\app\maven\apache-maven-3.8.6> tree
卷 Data 的文件夹 PATH 列表
卷序列号为 3EA4-3AC8
D:.
├─bin
├─boot
├─conf
│ └─logging
└─lib
├─ext
└─jansi-native
└─Windows
├─x86
└─x86_64
- lib放的都是jar包,是maven依赖的jar包
验证maven
C:\Users\smile>mvn --version
Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=UTF-8
Apache Maven 3.8.6 (84538c9988a25aec085021c365c560670ad80f63)
Maven home: D:\app\maven\apache-maven-3.8.6
Java version: 17.0.4.1, vendor: Oracle Corporation, runtime: D:\app安装夹\java\jdk-17.0.4.1
Default locale: zh_CN, platform encoding: UTF-8
OS name: "windows 11", version: "10.0", arch: "amd64", family: "windows"
需要修改conf/settings.xml
中的<localRepository>
为一个指定目录(默认是C盘~)
我们可修改在安装目录下创建文件夹
mvn_resp
我们把 <localRepository>/path/to/local/repo</localRepository>
粘贴出来,修改:
<localRepository>D:\app\maven\apache-maven-3.8.6\mvn_resp</localRepository>
因为中央服务器在国内下载的速度比较慢,所以需要配置一个私服
配置阿里云私服:修改conf/settings.xml
中的<mirrors>
标签,为其添加如下子标签:
<mirror>
<id>aliyunmaven</id>
<mirrorOf>*</mirrorOf>
<name>阿里云公共仓库</name>
<url>https://maven.aliyun.com/repository/public</url>
</mirror>
下一步我们配置jdk:这样我们未来创建项目默认使用我们的版本
<profile>
<id>1.8</id>
<activation>
<jdk>1.8</jdk>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
</properties>
</profile>
我们很多时候都是用IDEA进行使用maven,所以这一节还是非常非常主要的!
我们先去配置一下maven
在学习IDEA配置Maven之前,我们必须要去了解一下Maven坐标:
- maven坐标是资源的唯一标识
- 使用坐标来定义项目或者引入项目中所需要的依赖
- groupld:定义当前项目隶属于组织名称
- artifactld:定义当前Maven项目名称(通常是模块名称)
- version:定义当前项目的版本号
<groupId>org.example</groupId>
<artifactId>untitledasd</artifactId>
<version>1.0-SNAPSHOT</version>
MySQL驱动的版本:
<dependency>
<groupId>java</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.46</version>
</dependency>
新建一个模块
- 点击右侧maven面板,点击
+
- 选中对应项目的pom.xml文件,双击
我们平时可以直接点击右边生命周期,但是项目多了也不好,需要装个插件maven helper
- compile:编译
- clean:清理
- test:测试
- package:打包
- install:安装
编译后当前目录下多了个文件target
,我们在上面说过:所有编译、打包生成的文件都放在target
目录里
D:\文档\git\java\code\untitledasd>ls
pom.xml src target
D:\文档\git\java\code\untitledasd>tree target
卷 Data 的文件夹 PATH 列表
卷序列号为 3EA4-3AC8
D:\文档\GIT\JAVA\CODE\UNTITLEDASD\TARGET
├─classes
│ └─org
│ └─example
├─generated-sources
│ └─annotations
└─maven-status
└─maven-compiler-plugin
└─compile
└─default-compile
打包后生成jar字节码文件
执行test测试文件夹下的代码
install就是将当前的项目安装到本地仓库
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 package
,Maven就会执行default
生命周期,它会从开始一直运行到package
这个phase为止:
- validate
- ...
- package
如果我们运行mvn compile
,Maven也会执行default
生命周期,但这次它只会运行到compile
,即以下几个phase:
- validate
- ...
- compile
Maven另一个常用的生命周期是clean
,它会执行3个phase:
- pre-clean
- clean (注意这个clean不是lifecycle而是phase)
- post-clean
所以,我们使用mvn
这个命令时,后面的参数是phase,Maven自动根据生命周期运行到指定的phase。
更复杂的例子是指定多个phase,例如,运行mvn clean package
,Maven先执行clean
生命周期并运行到clean
这个phase,然后执行default
生命周期并运行到package
这个phase,实际执行的phase如下:
- pre-clean
- clean (注意这个clean是phase)
- validate
- ...
- package
在实际开发过程中,经常使用的命令有:
mvn clean
:清理所有生成的class和jar;
mvn clean compile
:先清理,再执行到compile
;
mvn clean test
:先清理,再执行到test
,因为执行test
前必须执行compile
,所以这里不必指定compile
;
mvn clean package
:先清理,再执行到package
。
大多数phase在执行过程中,因为我们通常没有在pom.xml
中配置相关的设置,所以这些phase什么事情都不做。
其实我们在执行
mvn install
,maven会自动帮我们执行生命周期前面的命令。
经常用到的phase其实只有几个:
- clean:清理
- compile:编译
- test:运行测试
- package:打包
执行一个phase又会触发一个或多个goal:
执行的Phase | 对应执行的Goal |
---|---|
compile | compiler:compile |
test | compiler:testCompile surefire:test |
goal的命名总是abc:xyz
这种形式。
看到这里,相信大家对lifecycle、phase和goal已经明白了吧?
其实我们类比一下就明白了:
- lifecycle相当于Java的package,它包含一个或多个phase;
- phase相当于Java的class,它包含一个或多个goal;
- goal相当于class的method,它其实才是真正干活的。
大多数情况,我们只要指定phase,就默认执行这些phase默认绑定的goal,只有少数情况,我们可以直接指定运行一个goal,例如,启动Tomcat服务器:
mvn tomcat:run
- 在
pom.xml
中编写<dependencies>
标签 - 在
<dependencies>
标签中使用<dependencies>
引入坐标 - 定义坐标的
groupld
,artifactld
,version
我们在网上找一个MySQL的驱动包,搜索mysql maven
<!-- 导入MySQL的驱动jar包-->
<dependencys>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>6.0.6</version>
</dependency>
</dependencys>
我们看到有爆红的,这个时候需要去下载,点击右边下载的按钮
按下alt + insert
或者alt + fn install
就可以打开面板,搜索驱动就好了
下面就会自动帮你构建好
<dependencys>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>6.0.6</version>
</dependency>
</dependencys>
通过设置依赖范围<scop>
可以设置对应的jar包的作用范围:编译环境、测试环境、运行环境
Maven定义了几种依赖关系,分别是compile
、test
、runtime
和provided
:
scope | 说明 | 示例 |
---|---|---|
compile | 编译时需要用到该jar包(默认) | commons-logging |
test | 编译Test时需要用到该jar包 | junit |
runtime | 编译时不需要,但运行时需要用到 | mysql |
provided | 编译时需要用到,但运行时由JDK或某个服务器提供 | servlet-api |
其中,默认的compile
是最常用的,Maven会把这种类型的依赖直接放入classpath。
test
依赖表示仅在测试时使用,正常运行时并不需要。最常用的test
依赖就是JUnit:
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.3.2</version>
<scope>test</scope>
</dependency>
runtime
依赖表示编译时不需要,但运行时需要。最典型的runtime
依赖是JDBC驱动,例如MySQL驱动:
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.48</version>
<scope>runtime</scope>
</dependency>
provided
依赖表示编译时需要,但运行时不需要。最典型的provided
依赖是Servlet API,编译的时候需要,但是运行时,Servlet服务器内置了相关的jar,所以运行期不需要:
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.0</version>
<scope>provided</scope>
</dependency>
要安装Maven,可以从Maven官网下载最新的Maven 3.6.x,然后在本地解压,设置几个环境变量:
我们也可使用docker安装maven私服,使用docker管理还是很方便的
docker search --limit 4 maven
docker run -d -p 8081:8081 -p 8082:8082 -p 8083:8083 --name maven -v D:\docker\maven\:/nexus-data --restart=always sonatype/nexus3
docker ps
docker exec -it maven /bin/bash
docker logs maven
接下来可以访问http://localhost:8081/
```
http://127.0.0.1:8081/
user:admin
passwd:admin123
```
maven有三种仓库:
- 本地仓库:存放本地的jap包
- 中央仓库:maven团队维护全球唯一
- 远程仓库:一般由公司团队搭建的私有仓库
引入包
下载jap包的时候,我们是在
pom.xml
写下包,然后maven在本地查看有没有包,如果没有到远程拉下来放到本地仓库。如果搭建了远程仓库,那么将来jar包的查找顺序变为:
本地仓库 –> 远程仓库 –> 中央仓库