第1章 Maven项目构建
Maven的两个核心功能:项目构建, 依赖(jar包)管理。
1.1 项目构建
在进行项目开发时,我们也会兼顾项目管理的工作,如添加依赖(jar包)、编译源码、单元测试、项目部署等操作。这一系列的操作就统称为“项目构建”
1.2 Maven是什么
Maven是一个项目构建工具。使用Maven可以自动化地完成项目构建。学习到本章后半段就会体会到
1.3 Maven的作用
A. 项目构建:自动化地对项目进行编译、测试、打包、部署
B. 依赖管理:管理jar包,解决jar包之间的冲突(多个相同的jar,却有不同的版本)
1.4 Maven项目的结构
不同IDE的构建目录各不相同,以下是随便写得例子,但是能说明问题:
eclipse | JBuilder | NetBeans | idea | ... |
src bin | src output | src classes | src target | ... |
而Maven的一个伟大之处在于,它统一了全世界的java项目结构:
1.5 安装Maven
因为Maven是Java开发的,所以必须先安装好JDK并配置好JAVA_HOME环境变量!
1.5.1 下载Maven
Maven下载地址: https://maven.apache.org/download.cgi
下载Maven后,解压到本地磁盘,解压目录中不要含有中文,也不要含有空格,解压后的目录如下:
1.5.2 环境变量
添加MAVEN_HOME环境变量,用于指定Maven的安装目录
修改Path环境变量,在其中追加Maven的bin目录
在命令行中输入"mvn -v",能看到以下内容,就说明Maven环境配置好了
1.6 阿里云镜像
在后续的学习中,Maven会从中央仓库下载所需的资源。但是Maven中央仓库下载速度非常慢,所以我们要指定一个下载速度较快的Maven仓库:Maven阿里云镜像仓库,打开Maven根目录下的conf目录,打开settings.xml,在mirrors元素中加入以下内容:
<mirror>
<id>nexus-aliyun</id>
<mirrorOf>central</mirrorOf>
<name>Nexus aliyun</name>
<url>http://maven.aliyun.com/nexus/content/groups/public</url>
</mirror>
1.7 Maven Hello Wolrd
手动创建一个Maven项目,编写代码,编译,并运行。注意目前手动创建MAVEN项目只是为了练习,后续我们会直接使用idea工具创建MAVEN项目的!
17.1 创建目录结构
注意:由于Maven是Java编写的,所以Maven自然地把项目当做一个对象来看待,而pom.xml就是一个用于描述当前项目对象的配置文件,每个Maven项目都必须有一个pom.xml配置文件
1.7.2 编写pom.xml
pom是项目对象模型(Project Object Model)的简称,一个典型的pom.xml配置文件如下:
<?xml versinotallow="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:schemaLocatinotallow="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.gao</groupId>
项目名 -->
<artifactId>foo</artifactId>
版本号:大版本.小版本.里程碑版本 -->
<version>0.0.1-SNAPSHOT</version>
打包方式,取值可以是:jar、war、pom -->
<packaging>jar</packaging>
</project>
里程碑版本 | 说明 |
SNAPSHOT | 开发版 |
alpha | 内部测试版 |
beta | 公开测试版 |
Release | 发布版 |
1.7.3 编写Java类
在foo\src\main\java\com\gao\demo目录下创建一个App.java,内容如下:
1.7.4 编译
进入命令行,进入pom.xml文件所在目录,编译Java源文件
mvn compile
注意:
1. 第一次使用mvn compile命令时,会下载对应的插件,下载到本地仓库中
2. 命令mvn compile会自动调用javac对项目中所有的Java源文件进行编译
3. Maven知道Java源文件的位置在哪,因为Maven约定了Java源文件必须在src/main/java下
4. 编译好的字节码文件会存放到target/classes下,这也是约定
5. 注意以上的警告:使用平台相关的字符编码GBK,构建项目是与平台相关的,我们构建项目不应该与平台相关,所以在pom.xml中再加入以下配置(在</project>上面添加即可)
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
6. 执行mvn命令时,必须在进入pom.xml文件所在目录!进入pom.xml文件所在目录!进入pom.xml文件所在目录!
1.7.5 运行
进入命令行,进入pom.xml文件所在目录,运行程序
mvn exec:java -Dexec.mainClass="com.gao.demo.App"
注意:
1. 第一次使用该命令,会下载对应的插件
2. -Dexec.mainClass用于指定包含main方法的类的“全限定名”,也就是“包名+类名”
3. Maven知道去target/classes目录下找com.gao.demo.App类,这也是约定
1.8 约定大于配置
Maven采用了约定大于配置的方式。也就是只要我们使用Maven来管理一个项目,那么该项目中源代码的位置,字节码的位置,配置文件的位置都是固定的,如下,以下一个名为foo的项目为例
目录 | 说明 |
/foo/ | 存放pom.xml |
/foo/src/main/java | 存放Java源代码 |
/foo/src/main/resources | 存放配置文件,比如mybatis-config.xml |
/foo/src/main/webapp | web应用根目录,等价于WebContent |
/foo/src/test/java | 存放测试代码 |
/foo/src/test/resources | 存放测试用的配置文件 |
约定大于配置的优点就是,配置大大减少了。
1.9 配置Maven本地仓库
Maven的本地仓库默认在C盘下,这样如果将来我们重做了系统,格式化了C盘,则仓库中的依赖也会全部丢失。在用户的家目录下可以看到这默认的本地仓库,我们可以将该仓库删除
然后我们直接把Maven的仓库位置修改到C盘以外的位置,我个人习惯把Maven的本地仓库放在Maven安装目录下的respository目录下,打开Maven根目录下的conf文件夹下的settings.xml,添加以下配置:
再次编译、运行Maven项目,会发现资源下载到了D:\apache-maven-3.8.4\repository下
1.10 依赖坐标
当我们把一个依赖的坐标写入pom.xml中的dependencies元素中后,在编译时Maven就会为我们下载对应的依赖。这个依赖会下载到本地仓库中,而不是下载到项目中。始终记住,项目中没有任何jar。项目中顶多只有依赖的坐标。
示例1:引入junit依赖
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
注意,引入一个依赖时,也会同时把该依赖相关的其他依赖一起引入进来
示例2:引入mysql依赖
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.27</version>
</dependency>
中央仓库地址: https://mvnrepository.com/
通过依赖坐标,可以在本地仓库找依赖,如果本地仓库没有,则可以继续拿着依赖坐标去远程仓库找!所以依赖坐标就是用来找依赖的!所以依赖坐标必须唯一!
1.11 Maven常用命令
Maven的命令格式如下:
mvn [plugin-name]:[goal-name]
命令 | 描述 |
mvn -v | 显示Maven版本信息 |
mvn compile | 编译src/main/java下的所有Java源文件 |
mvn clean | 清除target |
mvn test | 执行src/test/java下的测试用例 |
mvn package | 打包项目,在target下生成jar或war |
mvn install | 将打包好的jar或war存入到本地仓库中,供其他Maven项目使用 |
mvn compile 和 mvn clean我们已经熟悉了,下面学习其他的命令
1.11.1 mvn test
当执行mvn test命令时,Maven会自动去src/test/java目录下寻找所有名字以“Test”结尾的类,比如AppTest,然后再执行这些类中被@Test所标注的方法,这也是Maven的约定。所以我们按以下步骤测试这个命令:
步骤1:在src\test\java下创建com.gao.demo.AppTest类,在类中创建一个test方法,在其上添加一个@Test注解,注意使用@Test注解,必须先引入它:import org.junit.Test
步骤2:在pom.xml文件所在目录下,键入mvn test命令
1.11.2 mvn package
mvn package 用于打包Maven项目
可以看到在打包之前,先进行了test,如果想跳过test,则加入参数即可:
mvn package -Dmaven.test.skip=true
1.11.3 mvn install
mvn install 用于把当前Maven项目先打包,然后存入到本地仓库中,以便让其他的Maven项目使用
其他的Maven项目就可以引入我们这个项目的坐标,从而使用其中的类了。
1.12 Maven生命周期
Maven有3套生命周期:1. 默认生命周期;2. clean生命周期;3. site生命周期(不学)。
每个生命周期都包含多个阶段。比如默认生命周期的阶段包含:compile、test、package、install。当执行一个阶段的时候会先执行该阶段之前的所有阶段。比如在执行mvn test时,就会先执行compile阶段,再执行test阶段。比如在执行mvc install阶段的时候,就会先执行compile、test、package阶段,以此类推。
1.13 Maven插件和目标
我们已经知道,Maven的默认生命周期包含以下几个阶段:compile、test、package、install,而对于每个阶段的实现,Maven并没有写死,而是交给插件来完成,如下图所示:
深入一点,一个Maven插件就是一个或多个目标的集合。每个目标都完成一个独立的任务,更确切地说,Maven生命周期中的各个阶段是由插件中的某个特定目标完成的,如下图所示:
Maven有默认的插件,用默认插件的目标来实现各个阶段要做的事情。
示例1:插件的使用
<?xml versinotallow="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:schemaLocatinotallow="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.gao</groupId>
<artifactId>foo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.2.1</version>
<executions>
<execution>
<goals>
<goal>jar</goal>
</goals>
<phase>test</phase>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
可以看出,插件也是有坐标的。同时我们可以将插件中的某个目标绑定到生命周期的某个阶段上,当执行到该阶段时,对应的插件目标就会执行了
示例2:插件的目标也可以独立执行
1.15 Maven概念模型
1.16 Maven的优点
A. 项目构建:自动化地对项目进行编译、测试、打包、部署
B. 依赖管理:管理jar包,解决jar包之间的冲突(多个相同的jar,却有不同的版本)