官网:http://maven.apache.org/
Maven是自动化构建工具。
Maven简介
传统项目开发存在的问题
一个项目做成一个工程,造成工程比较庞大,需要使用多模块来划分项目;
项目中需要数量众多的jar包,需要手动下载并引入,并且多个项目需要的jar包存在重复的问题;
项目中需要的jar包有版本兼容的问题,需要手动解决;
项目中需要的jar包又依赖其它的jar包,需要手动解决。
Maven概述
-
Maven是 Apache 软件基金会组织维护的一款自动化构建工具,专注服务于Java平台的项目构建和依赖管理。Maven这个单词的本意是:专家,内行。读音是['meɪv(ə)n]或['mevn]。
-
Maven是目前最流行的自动化构建工具,对于生产环境下多框架、多模块整合开发有重要作用,Maven是一款在大型项目开发过程中不可或缺的重要工具。
-
Maven可以整合多个项目之间的引用关系,我们可以根据业务和分层需要任意拆分一个项目;
-
Maven提供规范的管理各个常用jar包及其各个版本,并且可以自动下载和引入项目中;
-
Maven可以根据指定版本自动解决jar包版本兼容问题;
-
Maven可以把jar包所依赖的其它jar包自动下载并引入项目。
类似自动化构建工具还有:Ant,Maven,Gradle。
构建过程中的各个环节:清理、编译、测试、报告、打包、安装、部署。
构建(build),是面向过程的(从开始到结尾的多个步骤),涉及到多个环节的协同工作。
- 清理:删除以前的编译结果,为重新编译做好准备。
- 编译:将Java源程序编译为.class字节码文件。
- 测试:针对项目中的关键点进行测试,确保项目在迭代开发过程中关键点的正确性。
- 报告:在每一次测试后以标准的格式记录和展示测试结果。
- 打包:将一个包含诸多文件的工程封装为一个压缩文件用于安装或部署。Java工程对应jar包,Web工程对应war包。
- 安装:在Maven环境下特指将打包的结果——jar包或war包安装到本地仓库中。
- 部署:将打包的结果部署到远程仓库或将war包部署到服务器上运行。
Maven核心概念
Maven能够实现自动化构建是和它的内部原理分不开的,这里从Maven的九个核心概念入手,看看Maven是如何实现自动化构建的。
- POM:一个文件,名称是pom.xml,pom翻译过来叫做项目对象模型。
maven把一个项目当作一个模型使用。控制maven构建项目的过程,管理jar依赖。 - 约定的目录结构:maven项目的目录和文件的位置都是规定好的。
- 坐标:是一个唯一的字符串,用来表示资源的。
- 依赖管理:管理你的项目中可以使用的jar文件。
- 仓库管理(了解):你的资源存放的位置。
- 生命周期(了解):maven工具构建项目的过程,就是生命周期。
- 插件和目标(了解):执行maven构建的时候用的工具叫做插件。
- 继承
- 聚合
Maven工具的安装和配置
确保安装了java环境,maven本身就是java写的,所以要求必须安装JDK。
查看java环境变量:echo %JAVA_HOME%
- 需要从Maven的官网(https://maven.apache.org/download.cgi)下载maven的安装包 apache-maven-3.3.9-bin.zip
- 解压安装包,解压到一个非中文目录。
子目录bin:执行程序,主要是mvn.cmd
conf:maven工具本身的配置文件settings.xml - 配置环境变量
在系统的环境变量中,指定一个H2_HOME的名称,指定它的值是maven工具安装目录,bin之前的目录。
M2_HOME=E:\D\Maven\apache-maven-3.6.3
再把M2_HOME加入到PATH中: - 验证,执行mvn -v
注意:需要配置JAVA_HOME,指定jdk路径。
C:\Users\51572>mvn -v
出现如下内容,maven安装配置正确。
Apache Maven 3.6.3 (cecedd343002696d0abb50b32b541b8a6ba2883f)
Maven home: E:\D\Maven\apache-maven-3.6.3\bin…
Java version: 1.8.0_201, vendor: Oracle Corporation, runtime: C:\Program Files\Java\JDK\jre
Default locale: zh_CN, platform encoding: GBK
OS name: “windows 10”, version: “10.0”, arch: “amd64”, family: “windows”
Maven的核心概念
Maven工程约定的目录结构
约定是大家都遵循的一个规则。
每一个maven项目在磁盘中都是一个文件夹(项目-Hello)
Hello/
—/src
------/main #放你主程序java代码和配置文件
---------/java #你的程序包和包中的java文件
---------/resources #你的java程序中要使用的配置文件
------/test #放测试程序代码和文件(可以没有)
---------/java #测试程序包和包中的java代码
---------/resources #测试java程序中要使用的配置文件
—/pom.xml #maven的核心文件(maven项目必须有)
第一个maven工程
按照如下步骤,实现第一个 maven 项目,以 maven 推荐的约定方式创建目录,类文件。
1.某个目录中创建文件夹 Hello
2.在 Hello 中创建子目录 src
3.拷贝 pom.xml 到 Hello 目录和 src 是同级放置的。
4.进入 src 目录,创建 main, test 目录
5.进入 main 目录,创建 java,resources 目录。
6.进入 java 目录,创建目录 com/bjpowernode/
6.在 com/bjpowernode/目录下创建 HelloMaven.java 文件,定义 int addNumber(int n1,n2){ return n1+n2};
定义 public static void main(String args[]) { System.out.prinltn(“Hello Manven”); //也可以调用 addNumber()方法 }
7.进入到 Hello 目录在,执行 mvn compile
8.进入到 target/classes 目录执行 java com.bjpowernode.HelloMaven
疑问:mvn compile
编译src/main目录下的所有java文件。编译过程中会下载很多插件。
1.为什么要下载?
maven工具执行的操作需要很多插件(java类–jar包)完成的。
2.下载什么东西了?
jar文件,叫做插件,插件是完成某些功能。
3.下载的东西存放到哪里了?
默认仓库(本机仓库):C:\Users\51572(登录操作系统的用户名).m2\repository
执行mvn compile,结果是在项目的根目录下生成target目录(结果目录),maven编译的java程序,最后形成的class文件都放在target目录中。
设置本机存放资源的目录位置(设置本机仓库):
1.修改maven的配置文件,maven安装目录/conf/settings.xml。(先备份settings.xml)
2.修改 ,指定你的目录(不要使用中文目录)。
仓库
仓库的概念
maven有仓库的概念。在Maven中,任何一个依赖、插件或者项目构建的输出,都可以称之为构件。Maven核心程序仅仅定义了自动化构建项目的生命周期,但具体的构建工作是由特定的构件完成的。而且为了提高构建的效率和构件复用,maven把所有的构件统一存储在某一个位置,这个位置就叫做仓库。
仓库存什么
仓库是存放东西的,Maven仓库存的是:
- Maven的插件,插件也是一些jar,这些jar可以完成一定的功能。
- 我们自己开发项目的模块
- 第三方框架或工具的jar包
仓库的类别
根据仓库存储的位置,把仓库分为本地仓库和远程仓库。
本地仓库,存在于当前电脑上,默认存放在c:\user.m2\repository中,为本机上所有的Maven工程服务。你也可以通过Maven的配置文件settings.xml中修改本地仓库所在的目录。
远程仓库,分为全世界范围内的开发人员提供服务的中央仓库、为全世界范围内某些特定的用户提供服务的中央仓库镜像、为本公司提供服务自己架设的私服。中央仓库是maven默认的远程仓库,其地址是:https://repo.maven.apache.org/maven2/
中央仓库,包含了绝大多数流行的开源Java构件,以及源码、作者信息、许可证信息等。一般来说,简单的Java项目依赖的构件都可以在这里下载得到。
私服是一种特殊的远程仓库,它是架设在局域网内的仓库服务,私服代理广域网上的远程仓库,供局域网内的Maven用户使用。当Maven需要下载构件的时候,它从私服请求,如果私服上不存在该构件,则从外部的远程仓库下载,缓存在私服上之后,再为Maven的下载请求提供服务。我们还可以把一些无法从外部仓库下载到的构件上传到私服上。
分类说明:
- 本地仓库:本机当前电脑上的资源存储位置,为本机上所有Maven工程提供服务。
- 远程仓库:不在本机上,通过网络才能使用。多电脑共享使用的。
- 中央仓库:通过Internet访问,为全世界所有Maven工程服务,最权威的。
- 中央仓库的镜像:架设在不同位置,欧洲、美洲、亚洲等每个洲都有若干的服务器,为中央仓库分担流量。减轻中央仓库的访问、下载的压力。所在洲的用户首先访问的是本洲的镜像服务器。
- 私服:在局域网环境中部署的服务器,为当前局域网范围内的所有Maven工程服务。公司中常常使用这种方式。
Maven对仓库的使用
maven仓库的使用不需要人为参与。
在Maven构建项目的过程中如果需要某些插件,首先会到Maven的本地仓库中查找,如果找到则可以直接使用;如果找不到,它会自动连接到外网,到远程中央仓库中查找;如果远程仓库中能找到,则先把所需要的插件下载到本地仓库,然后再使用,并且下次再用到相同的插件也可以直接使用本地仓库的;如果没有外网或者远程仓库中也找不到,则构建失败。
POM文件
即 Project Object Model 项目对象模型。Maven把一个项目的结构和内容抽象成一个模型,在xml文件中进行声明,以方便进行构建和描述,pom.xml是Maven的灵魂。所以maven环境搭建好之后,所有的学习和操作都是关于pom.xml的。
基本信息 | ||
---|---|---|
modelVersion | Maven模型的版本,对于Maven2和Maven3来说,它只能是4.0.0 | |
groupId | 组织id,一般是公司域名的倒写。格式可以为: 1. 域名倒写。例如:com.baidu 2. 域名倒写+项目名。例如:com.baidu.appolo | groupId、artifactId、version三个元素生成了一个Maven项目的基本坐标,在众多的maven项目中可以唯一定位到某一个项目。坐标也决定着将来项目在仓库中的路径及名称。 |
artifactId | 项目名称,也是模块名称,对应groupId中项目中的子项目。 | |
version | 项目的版本号。如果项目还在开发中,是不稳定版本,通常在版本后带-SNAPSHOT version使用三位数字标识,例如:1.1.0 | |
packaging | 项目打包的类型,可以是jar、war、rar、ear、pom,默认是jar | |
依赖 | ||
dependencies 和 dependency | Maven的一个重要作用就是管理jar包,为了一个项目可以构建或运行,项目中不可避免地会依赖很多其他的jar包,在Maven中这些jar就被称为依赖,使用标签dependency来配置。而这种依赖的配置正是通过坐标来定位的,由此我们也不难看出,maven把所有的jar包也都视为项目存在了。 | |
配置属性 | ||
properties | properties是用来定义一些配置属性的,例如project.build.sourceEncoding(项目构建源码编码方式),可以设置为UTF-8,防止中文乱码,也可以定义相关构建版本号,便于日后统一升级。 | |
构建 | ||
build | build表示与构建相关的配置,例如设置编译插件jdk版本。 | |
继承 | ||
parent | 在Maven中,如果多个模块都需要声明相同的配置,例如:groupId、version、有相同的依赖或者相同的组件配置等,也有类似Java的继承机制,用parent声明要继承的父工程的pom配置。 | |
聚合 | ||
modules | 在Maven的多模块开发中,为了统一构建整个项目的所有模块,可以提供一个额外的模块,该模块打包方式为pom,并且在其中使用modules聚合其他模块,这样通过本模块就可以一键自动识别模块间的依赖关系来构建所有模块,叫Maven的聚合。 |
坐标(gav)
Maven把任何一个插件都作为仓库中的一个项目进行管理,用一组(三个)向量组成的坐标来表示。坐标在仓库中可以唯一定位一个Maven项目。
groupId:组织名,通常是公司或组织域名倒序+项目名
artifactId:模块名,通常是工程名
version:版本号
需要特别指出的是,项目在仓库中的位置是由坐标来决定的:groupId、artifactId和version决定项目在仓库中的路径,artifactId和version决定jar包的名称。
依赖(dependency)
一个Maven项目正常运行需要其它项目的支持,Maven会根据坐标自动到本地仓库中进行查找。对于程序员自己的Maven项目需要进行安装,才能保存到仓库中。
不要maven的时候所有的jar都不是你的,需要去各个地方下载拷贝,用了maven所有的jar包都是你的,想要谁叫谁的名字就行,maven帮你下载。
Maven的生命周期
对项目的构建是建立在生命周期模型上的,它明确定义项目生命周期各个阶段,并且对于每一个阶段提供相对应的命令,对开发者而言仅仅需要掌握一小堆的命令就可以完成项目各个阶段的构建工作。
构建项目时按照生命周期顺序构建,每一个阶段都有特定的插件来完成。不论现在要执行生命周期中的哪个阶段,都是从这个生命周期的最初阶段开始的。
对于我们程序员而言,无论我们要进行哪个阶段的构建,直接执行相应的命令即可,无需担心它前边阶段是否构建,Maven都会自动构建。这也就是Maven这种自动化构建工具给我们带来的好处。
maven的生命周期:就是maven构建项目的过程,清理、编译、测试、报告、打包、安装、部署。
maven的命令:maven独立使用,通过命令完成maven的生命周期的执行。maven可以使用命令,完成项目的清理、编译、测试等等。
maven的插件:maven命令执行时,真正完成功能的是插件,插件就是一些jar文件、一些类。
单元测试(测试方法)
用的是junit,junit是一个专门测试的框架(工具)。
junit测试的内容:测试的是类中的方法,每一个方法都是独立测试的。方法是测试的基本单位(单元)。
maven借助单元测试,批量的测试你类中的大量方法是否符合预期的。
使用步骤:
1.加入依赖,在pom.xml中加入单元测试依赖:
junit
junit
4.11
test
2.在maven项目中的src/test/java目录下,创建测试程序。
推荐的创建类和方法的提示:
1.测试类的名称:Test + 你要测试的类名
2.测试的方法名称:test + 方法名称
例如:你要测试HelloMaven,创建的测试类就是TestHelloMaven。
@Test
public voic testAdd(){
测试HelloMaven的add方法是否正确
}
其中testAdd叫做测试方法,它的定义规则:
1.方法是public的,必须的。
2.方法没有返回值,必须的。
3.方法名称是自定义的,推荐Test+方法名称
4.在方法上面加入@Test
Maven的常用命令
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配置把主程序打包生成jar包或者war包)mvn install
:安装主程序(会把本工程打包,并且按照本工程的坐标保存到本地仓库中)mvn deploy
:部署主程序(会把本工程打包,按照本工程的坐标保存到本地库中,并且还会保存到私服仓库中。还会自动把项目部署到web容器中。)
注意:执行以上命令必须在命令行进入pom.xml所在目录!
插件
maven构建周期,由maven的插件plugin来执行完成。
官网插件说明:https://maven.apache.org/plugins/index.html
clean插件 maven-clean-plugin:2.5
clean阶段是独立的一个阶段,功能就是清除工程目前下的target目录。
resources插件 maven-resources-plugin:2.6
resources插件的功能就是把项目需要的配置文件拷贝到指定的目录,默认是拷贝src\main\resources目录下的文件到target\classes目录下。
compile插件 maven-compiler-plugin:3.1
compile插件执行时先调用resources插件,功能就是把src\main\java的源码编译成字节码class文件,并把编译好的class文件输出到target\classes目录下。
testResources和testCompile插件
单元测试所用的compile和resources插件和主程序是相同的,但执行的目标不同,testResources和testCompile是把src\test\java下的代码编译成字节码输出到target\test-classes目录下,同时把src\test\resources下的配置文件拷贝到target\test-classes下。
执行测试测试的插件是:maven-surefire-plugin:2.12.4
package打包插件 maven-jar-plugin:2.4
这个插件是把class文件、配置文件打包成一个jar包(war或其它格式)。
install安装插件 maven-install-plugin:2.4
把打成的包安装到本地仓库。
常用的插件
插件可以在自己的项目中设置,最常使用的是maven编译插件。设置项目使用的jdk版本时通过编译插件指定。
pom.xml文件中设置:
<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>
Maven在IDEA中的应用
IDEA集成Maven
在IDEA中设置Maven,让IDEA和Maven结合使用。
IDEA中内置了Maven,一般不使用内置的,因为用内置修改maven的设置时不方便。
使用自己安装的maven,需要覆盖idea中的默认配置,让idea指定maven安装位置等信息。
配置的入口:
file – Settings – Build, Execution, Deployment – Build Tools – Maven
Maven home directory:maven的安装目录
User settings file:就是maven安装目录conf/settings.xml配置文件
Local repository:本机仓库的目录位置
– Build Tools – Maven – Runner
VM Options:虚拟机参数 -DarchetypeCatalog=internal
JRE:你项目的jdk
-DarchetypeCatalog=internal,IDEA根据maven archetype(原型/骨架/模板)的本质,其实是执行mvn archetype:generate
命令,该命令执行时,需要指定一个archetype-catalog.xml文件。该命令的参数-DarchetypeCatalog,可选值为:remote、internal、local等,用来指定archetype-catalog.xml文件从哪里获取。
IDEA创建Maven版javase工程
maven-archetype-quickstart : 普通的java项目
IDEA创建Maven版web工程
maven-archetype-webapp : web工程
有时候如果网速不好,创建的时候会卡得比较久,这是因为maven这个骨架会从远程仓库加载archetype元数据,但是archetype又比较多,所以比较卡,这时候可以加个属性:archetypeCatalog=internal,表示仅使用内部元数据。
依赖管理
依赖的范围:compile、test、provided,默认采用compile。
compile | test | provided | |
---|---|---|---|
对主程序是否有效 | 是 | 否 | 是 |
对测试程序是否有效 | 是 | 是 | 是 |
是否参与打包 | 是 | 否 | 否 |
是否参与部署 | 是 | 否 | 否 |
Maven常用设置
全局变量
在Maven的pom.xml文件中,用于定义全局变量,POM中通过${property_name}的形式引用变量的值。
定义全局变量:
<properties>
<spring.version>4.3.10.RELEASE</spring.version>
</properties>
引用全局变量:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
Maven系统采用的变量:
<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 文件会分别在 compile 和 test-compile 阶段被编译,编译结果分别放到了 target/classes 和 target/test-classes 目录中,但是这两个目录中的其他文件都会被忽略掉,如果需要把 src 目录下的文件包放到 target/classes 目录中,作为输出的jar中的一部分,需要指定资源文件位置:
<build>
<resources>
<resource>
<!-- 所在目录 -->
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<!-- filtering选项false表示不启用过滤器,*.properties已经起到过滤的作用了。 -->
<filtering>false</filtering>
</resource>
</resources>
</build>