Maven
Maven的介绍
在整个软件开发的过程中,完成一个软件项目需要完成很多的工作:
- 分析项目的组成部分以及实现方法
- 设计项目所需技术、软件、人员以及时长,并组建团队进行开发
- 要编译代码—>开发人员自己测试代码—>把代码打包—>部署项目到测试服务器—>测试人员测试功能—>测试测试出 bug
- 开发人员需要修改bug—>开发人员自己测试代码—>把代码打包—>部署项目到测试服务器—>测试人员测试功能—>直到符合功能要求。
上面的过程有时会重复多次,大型项目中的项目构建比较复杂,有很多的配置文件,jar包等,而maven可以帮助我们从上述复杂的工作流程中解脱出来。
maven是一个自动化构建工具。
-
传统开发项目的弊端
- 有很多的模块,模块之间关系手动管理时会非常复杂繁琐
- 需要很多第三方jar包的支持,而且需要手动获取这些第三方jar包,手动管理它们的版本
- 需要手动管理jar文件相互之间的依赖,这导致配置程序所需第三方工具就会耗费大量的时间
-
使用maven可以改进项目的开发与管理
- maven可以管理jar文件
- maven可以自动下载jar包及其文档与源代码,并且自动管理jar包的版本
- 可以自动获取jar包之间的依赖
- 能够帮助开发人员编译文件、测试代码、将项目文件打包成jar、war文件
- 自动部署项目
-
项目的构建
构建是面向过程的,其实构建就是一些步骤。maven支持的构建包括:- 清理:将之前项目的编译结果删除,为重新编译做好准备
- 编译:将java源程序编译为字节码文件(maven可以实现批量编译,而javac一次只能编译一个源文件)
- 测试:针对项目中的关键点进行测试,确保项目在迭代开发过程中关键点的正确性(maven可以实现批量测试代码,能够同时测试多个功能)
- 报告:在每次测试后以标准的性格记录和展示结果
- 打包:将一个包含多个文件的工程封装为一个压缩文件用于安装或者部署。java工程对应jar包,web工程对应war包。(也就是说打包是得到项目的结果压缩文件,服务器可以通过该压缩文件安装或者部署项目)
- 安装:在Maven环境下特指将打包的结果——jar包或者war包安装到本地仓库中。
- 部署:将打包的结果部署到远程仓库或者war包部署到服务器上运行
-
maven的核心概念
- POM:project Object Model,即工程对象模型,指的是pom.xml文件。maven将一个项目当做一个模型来使用,通过改变该文件的一些配置,可以控制maven构建项目的整个过程,并且能够管理依赖。因此对maven项目的所有控制,都通过POM来实现
- 约定的目录结构:指的是maven项目的目录以及文件的位置都是早已经定义好的(即目录由maven创建模板,开发人员做一些小的改动)
- 坐标:是一个唯一的字符串,用于表示某一唯一资源
- 依赖管理:管理项目中所有的jar文件及其相互之间的依赖关系
- 仓库管理:仓库适用于存放资源和依赖的位置
- 生命周期:使用maven来构建项目的过程(即maven支持的构建步骤),称为生命周期
- 插件和目标:maven在构建项目过程中使用到的工具叫做插件
- 继承
- 聚合
这些步骤都可以通过maven命令来实现,而在IDEA中这些操作已经封装好,可以直接使用maven
Maven的核心概念
-
Maven约定的目录结构
一般情况下,我们习惯上采取的措施是:约定>配置>编码。maven的pom.xml文件记录了关于项目构建各个方面的设置,maven从pom.xml文件开始,按照约定的目录编译、测试、打包、部署、发布项目。 -
仓库
- 仓库指的是用于存放maven和项目使用的jar包(依赖)的位置
- 仓库的分类
- 本地仓库:即个人计算机上的文件夹,存放着各种jar包(其实这些jar包在我们的项目中被称为工具或者依赖,但他们其实也是一个个大大小小的项目)
- 远程仓库:指的是互联网上的公共仓库,其中包含三类
(a ) 中央仓库:最权威的、所有开发人员共享、集中使用的仓库,地址为https://repo.maven.apache.org
(b ) 中央仓库的镜像:是中央仓库的备份,在各大洲重要城市都存在镜像
(c ) 私服:公司内部,局域网中使用的仓库 - 仓库的使用
maven的使用不需要人为的干预,由maven自动实现。在使用时,maven会首先查找本地仓库,随后是私服,最后是镜像和中央仓库
-
插件和目标
maven工具在执行操作时需要使用到插件(java类以jar包的形式存在)来完成一些操作。这些插件会由maven默认从中央仓库下载到本地仓库。当然本地仓库的位置是可以修改的,开发人员可以通过修改pom文件中的<localRepository>
来实现仓库位置的修改。
由maven编译完成的字节码文件将被存放在项目根目录下的target结果文件中 -
POM
- POM指的是maven中的pom.xml文件,下面是pom文件中的一些基本配置
<modelVersion>
,是maven模型的版本,对于maven2和maven3来说,他只能是4.0.0
groupId
,指的是组织id,一般为公司域名的倒写 + 项目名称,如com.alibaba.apolo
artifactId
,是指项目idversion
,指的是项目的版本号,通常使用三位数字表示packaging
,指项目打包的目的类型,可以为jar、war、rar、ear、pom等,默认为jar- 坐标,由
groupId
、artifactId
、version
三个元素共同生成一个maven项目的基本坐标。这个坐标可以用于唯一定位到该项目,也决定了该项目在仓库中的路径和名称
- 依赖
在pom文件中使用<dependencies>
和<dependency>
来引入依赖,相当于java中的import
maven的一个重要作用为管理jar包,为了项目可以构建运行,不可避免的需要引入很多的jar包来帮助完成。这些jar包在maven中被称为依赖。由<dependency>
来配置。而依赖的配置就是通过坐标来实现的。这样不难看出maven将所有的jar包都当做项目来对待 - 配置属性
<properties>
标签,是用来定义一些maven中的属性的,如project.build.sourceEncoding
等 - 构建
<build>
标签,表示与构建相关的一些配置,如设置编译插件的jdk版本等设置 - 继承
parent,在maven中如果有多个模块都需要声明相同的配置(如groupId、version等),也有类似于java的继承机制。那就是可以使用parent标签声明要继承的父工程的pom配置 - 聚合
modules。在maven的多模块开发中,为了统一构建整个项目的所有模块,可以额外提供一个打包方式为pom的模块,并在其中适用<modules>
标签聚合其他模块。这样就可以通过本模块自动识别其他模块之间的依赖关系来构建模块了
- Maven的生命周期、命令和插件
- maven的生命周期:即为maven项目构建的整个过程。即清理、编译、测试、报告、打包、安装、部署等步骤。
- maven的命令:maven对所有的步骤都提供了相应的命令,通过使用这些命令,可以完成maven生命周期各个阶段的执行。
mvn clean
,即清理,会删除原本编译和测试的结果目录(即target),但是已经install到本地仓库的依赖并不会因此被删除。所以通过时间的推移,本地仓库中的依赖越来越多,会形成开发人员自己的依赖库。mvn compile
,编译,会在项目根目录下创建target文件,用于存放编译后的字节码文件mvn test-compile
,编译测试程序,同样存放在target文件夹下mvn test
,测试,会生成目录surefire-reports,保存测试结果mvn package
,打包主程序,按照pom.xml文件中的配置将其打包为指定形式的压缩文件mvn install
,安装主程序,会将本工程打包,并按照pom文件中的坐标存放在本地仓库中mvn deploy
,部署主程序,打包并保存在私服和本地仓库,还会自动把项目部署到web容器中
- maven插件
maven命令执行时,真正完成功能的是插件。使用<plugin>
和坐标来配置插件
maven依赖管理
maven的依赖范围使用<scope>
来配置,即
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
- scope的值有compile、test、provided。表示依赖起作用的范围(jar包在maven构建项目的那个步骤中生效),如上面代码中表示junit4.0依赖只在测试步骤中生效,在编译、打包等过程中都不会用到这个依赖。
- 在maven中,依赖的默认作用范围为compile,这些范围的含义为:
- complie,指在maven构建项目的所有环节都需要该依赖的存在,为maven构建项目的默认依赖范围
- test:只在测试程序中有效,因此在maven构建此项目的其他任何环节都不需要此依赖的参与
- provided:在编译测试时会需要提供该依赖,而打包、安装等环节则不需要该依赖包的存在(provided可以理解为在打包、安装等环节不会将这些依赖拷贝到target文件夹中,而在服务器部署此项目的时候,会由部署项目的人员提供所需依赖),如servlet依赖,只需要在编译测试程序中使用该依赖,而在部署的时候会由服务器提供相关依赖。
maven的常用操作
- maven的属性设置
在pom文件中的<properties>
标签中配置的属性,如:
<properties>
<project.build.sourceEncoding></project.build.sourceEncoding> ##用于配置编码
<maven.compiler.source></maven.compiler.source> ##用于设定编译的jdk版本
<maven.compiler.target></maven.compiler.target> ##用于设定运行项目的jdk版本
</properties>
- maven中的全局变量
全局变量为在<properties>
中自定义的属性- 在
<properties>
中使用自定义标签配置全局变量 - 在pom文件的其他位置使用
${全局变量名}
使用全局变量
全局变量一般会用于定义依赖的版本号等会复用多次的字符串
- 在
<properties>
<spring.version>5.2.5</spring.version>
</properties>
<dependency>
<version>${spring.version}</version>
</dependency>
- 指定资源插件
在没有指定资源插件时,使用maven编译代码只会将resources文件中的配置文件拷贝到target/classes文件下,而对于java文件夹下的非java文件不做处理。但是对于一些需要在java文件中添加配置文件的情况(如MyBatis的Mapper文件),就需要使用资源插件来将这些文件也拷贝到target中
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
</includes>
<filtering>false</filtering>
</resource>
<resources>
</build>