maven
一、maven 是什么
Maven是基于项目对象模型(POM),可以通过一小段描述信息来管理项目的构建,报告和文档的软件项目管理工具。是一个异常强大的构建工具,能帮我们自动化构建过程,从编译、运行单元测试、生成文档、打包和部署,我们只需要输入见得的Maven命令即可。
Maven是java编写的,因此可以跨平台。总的来说,Maven 简化了工程的构建过程,并对其标准化。它无缝衔接了编译、发布、文档生成、团队合作和其他任务。Maven 提高了重用性,负责了大部分构建相关的任务
Maven不仅仅是构建工具,还是依赖管理工具和项目信息管理工具,还有一个强大的功能就是能够自动下载项目依赖的第三方库,Maven通过坐标来准确的定位到每一个jar包,并自动帮我们下载。
二、什么是 maven 坐标?
Maven的很强大的一个功能就是管理项目依赖,为了能自动化的精确获取到项目依赖,Maven就必须为其唯一标识,Maven通过坐标来构建唯一标识。
平面几何中,使用(x,y)坐标来表示平面中的任何一个点。Maven中拥有数量巨大的构件,就是jar、war等文件,Maven自己创建了一种坐标规则,只要我们指定争取的坐标,Maven就会到中央仓库中下载这些构建,Maven的中央仓库中包含了世界上流行的大部分构件。
坐标详解
我们来看一组坐标 <groupId>com.cad.maven</groupId> <artifactId>HelloWorld</artifactId> <version>0.0.1</version> <packaging>jar</packaging>
-
groupId:组织名称。项目属于哪个组。例如Spring-core,Spring-context都是属于SpringFramework组的。
-
artifactId:项目名称。
-
version:定义当前项目的版本
-
packaging:定义项目的打包方式。例如jar、war。不指定默认为jar
三、什么是依赖管理?
根元素project下的dependencies可以包含一个或多个 dependency元素,以声明一个或多个项目依赖。
每个依赖可以包含以下元素。
<groupId>:依赖组织名称 <artifactId>:依赖项目名称 <version>:版本 <scope>:依赖范围 <type>:依赖类型,对应于项目坐标定义的packing。默认值为jar <optional>:标记依赖是否可选 <exclusions>:用来排除传递性依赖
(一)依赖范围
依赖范围就是用来控制依赖应该在何时存在,例如junit包只需要在测试时存在,项目正式运行时就不需要了。
Maven有以下几种依赖范围
-
compile:没有指定,默认使用该依赖范围。使用此依赖范围,对于主代码、测试、运行时都会被引入各自的classpath。例子是spring-core,在主代码、测试、运行时都需要这个依赖。
-
test:测试依赖范围。使用此依赖范围的Maven依赖,只会被测试classpath引入。例子是JUnit,只有在测试时需要。
-
provided:使用此依赖范围的Maven依赖,会被主代码、测试等classpath引入,在运行时无效。例子是servlet-api,编译主代码和测试时需要,但在运行时由于容器会提供,所以可能会出现冲突,就不需要Maven再引入依赖。
-
runtime:运行时依赖范围。使用此依赖范围的Maven依赖,只有项目运行时会引入依赖。例子是JDBC驱动,在编译主代码时无效,只有测试运行还有运行时需要引入。
(二)依赖传递
我们说一个简单的例子,例如我们的B项目依赖C项目,我们的A项目依赖于B项目,C项目的很多依赖在A项目中也需要,Maven有依赖传递机制,我们A项目既然依赖了B项目,
就不需要考虑B项目依赖了什么,也不用担心使用不了C项目的依赖,再重复定义依赖,Maven会解析各个直接依赖的pom文件,将那些间接依赖引入到当前项目中。
(三)依赖传递范围
总结: 当第二依赖的范围是compile的时候,传递性依赖的范围与第一直接依赖的范围一致。 当第二直接依赖的范围是test的时候,依赖不会得以传递。 当第二依赖的范围是provided的时候,只传递第一直接依赖范围也为provided的依赖,且传递性依赖的范围同样为 provided; 当第二直接依赖的范围是runtime的时候,传递性依赖的范围与第一直接依赖的范围一致,但compile例外,此时传递的依赖范围为runtime;
(四)依赖冲突
比如我们A项目依赖B项目,B项目依赖C项目。B项目依赖JUnit3.0版本,C项目依赖JUnit4.0版本,并且依赖范围都是compile。那么这时候就出现了冲突,A项目会依赖哪个呢? Maven使用了就近原则,会使用距离A项目近的版本,所以会使用B项目的JUnit3.0版本。 如果一个pom文件中引入了两个不同版本的相同依赖,那么越靠近pom文件下面的越近。
(五)可选依赖
比如我们A项目依赖B项目,B项目依赖C项目,设置的依赖范围都是compile。但是我们的A项目根本就不需要C项目,
这时候就可以设置C项目的可选依赖,有个 <optional></optional>标签,设置为true则依赖不会传递,设置为false,
依赖继续传递,这就是可选依赖。我们把C项目的可选依赖设置为true,A项目中就不会再引用C项目。
(六)排除依赖
我们的可选依赖可以让某个依赖不再传递,但这时就出现了一种情况,我们D依赖A项目,但是D项目也需要C,这时候C项目传递不过来,就产生了很多麻烦。这时候可以使用排除依赖,排除依赖可以把自己不需要的依赖给排除。
我们在C项目排除A项目 <dependencies> <dependency> <groupId>com.cad.maven</groupId> <artifactId>SecondMaven</artifactId> <version>0.0.1-SNAPSHOT</version> <scope>test</scope> //排除A项目 <exclusions> <exclusion> <groupId>com.cad.maven</groupId> <artifactId>FirstMaven</artifactId> </exclusion> </exclusions> </dependency> </dependencies>
(七)归类依赖
我们的项目依赖spring,Spring项目分为很多个模块,例如Spring-core-4.0.jar,Spring-bean-4.0.jar等等。
等到我们项目需要更新Spring的时候,由于版本号都一样,所以我们是否可以将版本号给用一个常量存放,然后更新Spring时只需要改变常量的值即可。这样可以省去很多时间。
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="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.cad.maven</groupId> <artifactId>ThirdMaven</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>ThirdMaven</name> <url>http://maven.apache.org</url> <properties> <springframework.version>4.5</springframework.version> </properties> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${springframework.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>${springframework.version}</version> </dependency> </dependencies> </project>
(八) 优化依赖
通过前面的学习了解,Maven会自动解析所有直接依赖和传递依赖,并且判断依赖范围,最后项目得到的的依赖被称为已解析依赖。
我们可以通过mvn dependency:list来查看当前项目已解析依赖并且显示其范围:
我们可以通过mvn dependency:tree命令来查看当前项目依赖树
四、Maven仓库
Maven可以在某个统一的位置存储所有项目的依赖,这个位置就是仓库。Maven项目中只需要声明依赖的坐标,Maven会根据坐标自动寻找仓库中的依赖,并使用他们。而我们的项目也可以安装部署到仓库中,使其他项目使用。
根据Maven坐标定义每个构建在仓库中唯一存储路径大致为:groupId/artifactId/version/artifactId-version.packaging。
仓库的分类
Maven仓库分为本地仓库和远程仓库。Maven根据坐标寻找依赖时,会先到本地仓库查找,如果有则直接使用,如果没有则到远程仓库查找,如果查找到则下载到本地仓库使用,没有查找到就报错。
远程仓库又分为中央仓库和私服还有其他公开的远程仓库。私服是一种特殊的远程仓库,我们可以在公司内部部署一个私服,这样每个员工使用依赖时就不用每个人都去中央仓库下载,而是去局域网的私服下载,还可以把公司内部的项目放在私服上,供所有人使用,节省了带宽和时间。
本地仓库
默认情况下,本地仓库的地址是用户目录下的.m2/repository/ ,但是我们可以编辑settings.xml文件来自己设置目录,前面我们有讲过,就不再多说。
中央仓库
默认的中央仓库地址是http://repo1.maven.org/maven2。中央仓库包含了世界上大部分开源依赖。
私服
私服架设在局域网内,供局域网内的用户使用。Maven需要下载依赖时,先请求私服,如果私服没有,则从外部的远程仓库下载,自己还可以向私服上上传自己的项目,供局域网使用。
私服有很多优点。
- 节省自己带宽:大量对于外部仓库的访问会占用很多带宽。
- 没网的时候也可以使用
- 可以部署自己的项目
后面我们会详细介绍私服的搭建。
配置其他远程仓库
有时候我们默认的中央仓库无法满足我们的需求,可能项目需要的依赖存在于其他公开的远程仓库。例如JBoss Maven仓库,可以在我们的pom文件中配置该仓库。
配置JBoss Maven仓库 <repositories> <repository> <!--唯一id--> <id>jboss</id> <name>JBoss Repository</name> <!--仓库的url地址--> <url>http://repository.jboss.com/maven2/</url> <!--开启发布版本下载支持--> <releases> <enabled>true</enabled> </releases> <!--关闭快照版本下载支持--> <snapshots> <enabled>false</enabled> </snapshots> <!--使用默认布局--> <layout>default</layout> </repository> </repositories>
快照版本
Maven中任何一个项目依赖都需要有唯一的版本。例如1.0, 2.3.1 , 4.2-SNAPSHOT.
其中1.0,2.3.1都是发布版本,4.2-SNAPSHOT是快照版本。
为什么要区别发布版本和快照版本呢?
A开发一个项目的B模块,C开发D模块,D模块依赖B模块。A需要经常将自己的B模块更新供D使用。Maven每个坐标都是唯一的,A将自己的项目发布为2.1版本供C调用,那么有一些微小的改动,就需要发布2.2,2.3等版本,造成版本号的滥用。Maven的快照就是解决这个问题,A只需要将自己的版本设置为2.1-SNAPSHOT,发布到私服中,Maven会自动为项目打上时间戳,有了时间戳,Maven就能找到该项目的最新版本,C开发D模块时,D模块会自动的检查模块B的2.1-SNAPSHOT是否是最新,发现有更新便下载。
快照版本应该只在组织内部或模块依赖间使用,真正发布还是要发布正式版。
五、Maven的安装和配置
1.先从官网下载Maven,我这里下载的最新版 apache-maven-3.5.0-bin
2.下载成功后要配置Maven环境变量
3.测试是否安装成功,在系统命令行中执行命令:mvn –v
4.在Maven安装的目录的conf下有settings.xml文件,这是Maven的全局配置文件 我们可以在这儿配置本地仓库的地址,仓库后面会详解,里面会存放Maven下载的插件等 仓库地址默认系统的用户目录下的.m2/repository 我们自己来改变一下,当然我们
5.我们先运行一条简单的命令 mvn help:system,该命令会打印出所有的java系统属性和环境变量。 运行这条命令主要目的是第一次运行Maven命令时,会自动下载Maven的插件,包括pom文件和jar,都被下载到了本地仓库中。
六、maven 怎样创建 Java 项目?
使用Archetype生成项目骨架
Maven项目有一些约定,在根目录放pom.xml文件,src/main/java中放源码等等。如果我们每次创建Maven项目都需要自己来创建这个骨架的话,估计会烦的要命。Maven为我们提供了Archetype来帮助我们快速构建项目骨架。
我们在使用mvn archetype:generate命令生成项目骨架,Maven会有很多骨架供我们选择,也会提供一个默认的骨架,我们直接回车,然后会让我们输入groupid、artifactid、version、package等,然后就可以生成完整的项目骨架,极其方便。
七、maven 怎样创建 parent 项目?
<parent> <groupId>com.cad.maven</groupId> <artifactId>ParentProject</artifactId> <version>0.0.1-SNAPSHOT</version> </parent>
八、maven 如何创建 Java web 项目?
九、什么是 maven module? Maven聚合
在大型项目中,可能会有很多模块,在Maven中可以将这些模块给聚合成一个项目。
1.我们首先需要创建一个空的Maven项目,来去聚合其他模块,该模块的packaging必须为pom
2.通过<module>标签聚合其他项目,该被聚合的项目路径必须放在聚合项目pom文件的同一路径下 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="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.cad.MavenWeb</groupId> <artifactId>WebDemo</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>pom</packaging> <modules> <module>WebServlet</module> <module>WebService</module> </modules> </project>
3.我们执行一下编译命令,Maven会首先解析聚合模块的pom,分析需要构建的模块,然后根据顺序构建各个模块
十、maven module 与 project 有什么区别?
1.maven project和module相当于父子关系。
2.当新建的项目中不存在父子关系时使用project。
3.当项目中存在父子关系时用project做父工程,module做子工程,module工程必须有父工程。
十一、maven 如何编译源代码?maven 如何测试项目?maven 怎样打包?
常用Maven命令总结
Maven的命令要在根在目录中去执行
Mvn compile: 编译命令 Mvn clean: 清除命令,清除已经编译好的class文件,具体说清除的是target目录中的文件 Mvn test: 测试命令,该命令会将test目录中的源码进行编译 Mvn package: 打包命令 Mvn install: 安装命令,会将打好的包,安装到本地仓库 命令是可以组合的: Mvn clean compile:先清空再编译 mvn clean test命令:先执行clean,再执行test,通常应用于测试环节 mvn clean package:先执行clean,再执行package,将项目打包,通常应用于发布前 执行过程: 清理————清空环境 编译————编译源码 测试————测试源码 打包————将编译的非测试类打包 mvn clean install:先执行clean,再执行install,将项目打包,通常应用于发布前 执行过程: 清理————清空环境 编译————编译源码 测试————测试源码 打包————将编译的非测试类打包 部署————将打好的包发布到资源仓库中
十二、maven 怎样安装到本地仓库?
1、在Maven安装的目录的conf下有settings.xml文件,这是Maven的全局配置文件 我们可以在这儿配置本地仓库的地址
2、我们先运行一条简单的命令 mvn help:system,该命令会打印出所有的java系统属性和环境变量。 运行这条命令主要目的是第一次运行Maven命令时,会自动下载Maven的插件,包括pom文件和jar,都被下载到了本地仓库中
3、我们其他的Maven项目如何使用我们的项目呢,我们可以使用install命令将我们的jar包安装到本地仓库,然后在其他项目中通过gav来引用
十三、maven 编译时,如何跳过测试代码?
目前用到的方法如下,本文会持续更新~
方法一:pom文件添加如下配置:
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
</plugins>
方法二:
-DskipTests,不执行测试用例,但编译测试用例类生成相应的class文件至target/test-classes下。
-Dmaven.test.skip=true,不执行测试用例,也不编译测试用例类。
在eclipse中run as执行,如:clean install -Dmaven.test.skip=true
maven下载源码指令:
mvn dependency:sources
mvn dependency:resolve -Dclassifier=javadoc
命令使用方法:首先进入到相应的pom.xml目录中,然后执行以上命令:
第一个命令是尝试下载在pom.xml中依赖的文件的源代码。
第二个命令:是尝试下载对应的javadocs
但是有可能一些文件没有源代码或者javadocs
maven 通过 Tomcat 插件,如何运行 Java web 项目?
maven 怎样发布到 Tomcat?
maven 如何产生 site?