Maven

资料以及学习来自狂神说,还是黑马?还是尚硅谷?麻了我给忘了,看个意思意思就行

简介

Maven项目对象模型(POM),可以通过一小段描述信息来管理项目的构建,报告和文档的项目管理工具软件。
Maven 除了以程序构建能力为特色之外,还提供高级项目管理工具。由于 Maven 的缺省构建规则有较高的可重用性,所以常常用两三行 Maven 构建脚本就可以构建简单的项目

  • Maven 可以整合多个项目之间的引用关系,我们可以根据业务和分层需要任意拆分一个项目;
  • Maven 提供规范的管理各个常用 jar 包及其各个版本,并且可以自动下载和引入项目中;
  • Maven 可以根据指定版本自动解决 jar 包版本兼容问题;
  • Maven 可以把 jar 包所依赖的其它 jar 包自动下载并引入项目;

构建(build),是面向过程的(从开始到结尾的多个步骤),涉及到多个环节的协同工作。

  1. ①清理:删除以前的编译结果,为重新编译做好准备
  2. ②编译:将Java源程序编译为字节码文件
  3. ③测试:针对项目中的关键点进行测试,确保项目在迭代开发过程中关键点的正确性
  4. ④报告:在每一次测试后以标准的格式记录和展示测试结果
  5. ⑤打包:将一个包含诸多文件的工程封装为一个压缩文件用于安装或部署。Java 工程对应 jar 包,Web工程对应war包
  6. ⑥安装:在Maven环境下特指将打包的结果——jar包或war包安装到本地仓库中
  7. ⑦部署:将打包的结果部署到远程仓库或将war包部署到服务器上运行

安装与配置

安装教程参考:https://blog.csdn.net/u012660464/article/details/114113349

安装路径:Maven – Download Apache Maven

安装前提:安装jdk并配置好JAVA_HOME环境

配置 Maven 的环境变量

  1. MAVEN_HOME=maven安装目录或M2_HOME=maven安装目录
  2. path=%MAVEN_HOME%/bin

验证:控制台:mvn -v

解决Maven报错

彻底解决Could not transfer artifact org.apache.maven.plugins问题 - 我是一个邓疯子 - 博客园 (cnblogs.com)

Maven目录结构

projectName
|—src
|—|—main
|—|—|—java
|—|—|—resources
|—|—test
|—|—|—java
|—|—|—resources
|—pom.xml

  • src:源代码
  • main:主程序
  • java:主程序的 java 源码
  • resources:主程序的配置文件
  • test:测试程序
  • java:测试程序的 java 源码
  • resources:测试程序的配置文件
  • pom.xml:Maven 工程的核心配置文件

POM

基本信息

  • groupId:组织名称,域名的倒写
  • artifactId:项目名称
  • version:版本号
  • packaging:项目打包类型:war、jar

依赖

  • dependencies 和dependency:Maven 的一个重要作用就是管理 jar 包,为了一个项目可以构建或运行,项目中不可避免的,会依赖很多其他的 jar 包,在 Maven 中,这些 jar 就被称为依赖,使用标签 dependency 来配置。而这种依赖的配置正是通过坐标来定位的

配置属性

  • properties :properties 是 用 来 定 义 一 些 配 置 属 性 的 , 例 如project.build.sourceEncoding(项目构建源码编码方式),可以设置为UTF-8,防止中文乱码,也可定义相关构建版本号,便于日后统一升级

构建

  • build :build 表示与构建相关的配置,例如设置编译插件的 jdk 版本

继承

  • parent :在 Maven 中,如果多个模块都需要声明相同的配置,例如:groupId、version、有相同的依赖、或者相同的组件配置等,也有类似 Java 的继承机制,用 parent 声明要继承的父工程的 pom 配置。

聚合

  • modules:在 Maven 的多模块开发中,为了统一构建整个项目的所有模块,可以提供一个额外的模块,该模块打包方式为 pom,并且在其中使用 modules 聚合的其它模块,这样通过本模块就可以一键自动识别模块间的依赖关系来构建所有模块,叫 Maven 的聚合

仓库

Maven核心程序仅仅定义了自动化构建项目的生命周期,但具体的构建工作是由特定的构件完成的。而且为了提高构建的效率和构件复用,maven把所有的构件统一存储在某一个位置,这个位置就叫做仓库。

存放的东西

  1. Maven 的插件,插件也是一些 jar,这些 jar 可以完成一定的功能。
  2. 我们自己开发项目的模块
  3. 第三方框架或工具的 jar 包

仓库类别

  • 本地仓库

    存在于当前电脑上,默认存放在.m2\repository中,为本机上所有的Maven工程服务。你也可以通过Maven的配置文件Maven_home/conf/settings.xml中修改本地仓库所在的目录。 是用户的主目录,windows系统中是 c:/user/登录系统的用户名

    image-20220803162924567

  • 远程仓库

    分为为全世界范围内的开发人员提供服务的中央仓库、为全世界范围内某些特定的用户提供服务的中央仓库镜像、为本公司提供服务自己架设的私服。中央仓库是maven默认的远程仓库,其地址是:https://mvnrepository.com/

    • 中央仓库,包含了绝大多数流行的开源Java构件,以及源码、作者信息、许可证信息等。一般来说,简单的Java项目依赖的构件都可以在这里下载得到。
    • 私服是一种特殊的远程仓库,它是架设在局域网内的仓库服务,私服代理广域网上的远程仓库,供局域网内的Maven用户使用。当Maven需要下载构件的时候,它从私服请求,如果私服上不存在该构件,则从外部的远程仓库下载,缓存在私服上之后,再为Maven的下载请求提供服务。我们还可以把一些无法从外部仓库下载到的构件上传到私服上

Maven的生命周期及常用命令

生命周期

构建项目时按照生命周期顺序构建,每一个阶段都有特定的插件来完成。不论现在要执行生命周期中的哪个阶段,都是从这个生命周期的最初阶段开始的

Maven的常用命令

  1. mvn clean
    清理(会删除原来编译和测试的目录,即 target 目录,但是已经 install 到仓库里的包不会删除)
  2. mvn compile
    编译主程序(会在当前目录下生成一个 target,里边存放编译主程序之后生成的字节码文件)
  3. mvn test-compile
    编译测试程序(会在当前目录下生成一个 target,里边存放编译测试程序之后生成的字节码文件)
  4. mvn test
    测试(会生成一个目录surefire-reports,保存测试结果)
  5. mvn package
    打包主程序(会编译、编译测试、测试、并且按照 pom.xml 配置把主程序打包生成 jar 包或者war 包)
  6. mvn install
    安装主程序(会把本工程打包,并且按照本工程的坐标保存到本地仓库中)
  7. mvn deploy
    部署主程序(会把本工程打包,按照本工程的坐标保存到本地库中,并且还会保存到私服仓库中。还会自动把项目部署到 web 容器中)。

注意:执行以上命令必须在命令行进入 pom.xml 所在目录

插件

maven 过程构建周期,由 maven 的插件 plugin 来执行完成。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
<plugins>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.2</version>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
</plugin>
</plugins>
</pluginManagement>

插件可以在自己的项目中设置,最常使用的是 maven 编译插件。设置项目使用的 jdk 版本时通过编译插件指定。

pom.xml 文件中设置。

1
2
3
4
5
6
7
8
9
10
11
12
13
<build> 
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>

坐标(gav)

Maven 把任何一个插件都作为仓库中的一个项目进行管理,用一组(三个)向量组成的坐标来表示。坐标在仓库中可以唯一定位一个 Maven 项目。

groupId:组织名,通常是公司或组织域名倒序+项目名

artifactId:模块名,通常是工程名

version:版本号

依赖(dependency)

一个 Maven 项目正常运行需要其它项目的支持,Maven 会根据坐标自动到本地仓库中进行查找。对于程序员自己的 Maven 项目需要进行安装,才能保存到仓库中

依赖范围

compile test provided
对主程序是否有效
对测试程序是否有效
是否参与打包
是否参与部署

全局变量

在 Maven 的 pom.xml 文件中,用于定义全局变量,POM 中通过${property_name}的形式引用变量的值。

定义全局变量:

1
2
3
<properties>
<spring.version>4.3.10.RELEASE</spring.version>
</properties>

引用全局变量:

1
2
3
4
5
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>

Maven 系统采用的变量:

1
2
3
4
5
6
<properties>
<maven.compiler.source>1.8</maven.compiler.source> 源码编译 jdk 版本
<maven.compiler.target>1.8</maven.compiler.target> 运行代码的 jdk 版本
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> 项目构建使用的编码,避免中文乱码
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> 生成报告的编码
</properties>

指定资源位置

src/main/java 和 src/test/java 这两个目录中的所有*.java 文件会分别在 comile 和 test-comiple 阶段被编译,编译结果分别放到了 target/classes 和 targe/test-classes 目录中,但是这两个目录中的其他文件都会被忽略掉,如果需要把 src 目录下的文件包放到 target/classes 目录,作为输出的 jar 一部分。需要指定资源文件位置。以下内容放到标签中。

1
2
3
4
5
6
7
8
9
10
11
12
13
<build>
<resources>
<resource>
<directory>src/main/java</directory><!--所在的目录-->
<includes><!--包括目录下的.properties,.xml 文件都会扫描到-->
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<!—filtering 选项 false 不启用过滤器, *.property 已经起到过滤的作用了 -->
<filtering>false</filtering>
</resource>
</resources>
</build>

包引入错误

错误

image-20220804135048590

正确

1
2
3
4
5
6
7
8
9
10
11
12
<dependency>
<groupId>jakarta.servlet.jsp</groupId>
<artifactId>jakarta.servlet.jsp-api</artifactId>
<version>3.0.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<version>5.0.0</version>
<scope>provided</scope>
</dependency>