Maven项目管理工具
Maven
Maven简介
什么是 Maven?
Maven 是一个项目管理的工具。Maven 为我们开发人员提供了构建一个完整的生命周期的框架。Maven 使用标准的目录结构和默认构建生命周期,我们可以使用它自动完成项目的基础工具建设。
- 包含一个项目对象模型(Project Object Model)
- 一组标准集合
- 一个项目生命周期(Project Lifecycle)
- 一个依赖管理系统(Dependency Management System)
- 用来运行定义在生命周期阶段(phase)中插件(plugin)目标(goal)的逻辑
Maven 是干什么的?
它是 Apache 的开源项目,主要做 Java 平台的三类事情:项目构建、依赖管理以及项目信息管理,可以防止我们做一些重复的事情。
举个例子:假如有两个项目,需要引入相同的 jar,我们在两个地方都引入,那就是做了重复的事情,我们可以在一个公共的地方引入一次 jar 即可,例如父 pom.xml 中或者公共的 jar 中。
Maven除了具备Ant的功能外,还增加了以下主要功能:
- 使用Project Object Model来对软件项目管理
- 内置了更多的隐式规则,使得构建文件更加简单
- 内置依赖管理和Repository实现依赖的管理和统一存储
- 内置了软件构建的生命周期
Project Object Model(pom)
- 一个项目所有的配置都放在POM文件中
- 定义项目的类型、名字、管理依赖关系,定制插件的行为等
- 在POM中,groupId、artifactId、packagin、version叫做maven坐标
- 它能唯一的确定一个项目
- 有了maven坐标,我们就可以用它来指定我们的项目所依赖的其他项目、插件、或者父项目
Maven内置隐式规则
目录 | 目的 |
---|---|
${basedir} | 存放pom.xml和所有的子目录 |
${basedir}/src/main/java | 项目的java源代码 |
${basedir}/src/main/resources | 项目的资源,比如说property文件,springmvc.xml |
${basedir}/src/test/java | 项目的测试类,比如说Junit代码 |
${basedir}/src/test/resources | 测试用的资源 |
${basedir}/src/main/webapp/WEB-INF | web应用文件目录,web项目的信息 比如存放web.xml、本地图片、jsp视图页面 |
${basedir}/target | 打包输出目录 |
${basedir}/target/classes | 编译输出目录 |
${basedir}/target/test-classes | 测试编译输出目录 |
Test.java | Maven只会自动运行符合该命名规则的测试类 |
~/.m2/repository | Maven默认的本地仓库目录位置 |
Maven生命周期的各个阶段
Maven依赖管理
- 我们能够通过maven坐标确定一个项目
- 可以用它来解决依赖关系
- 在POM中,依赖关系是在dependencies部分中定义的
Maven 下载和安装
maven是依赖于jdk,在安装 maven 之前,请先安装好 jdk。
官网下载安装包
Maven 官网下载地址 ,选择自己想要的版本和系统的安装包进行下载。
解压安装包
下载的安装包为:apache-maven-x.x.x-bin.zip
配置环境变量
Mac版如下:
1 | bogon:~ jinglv$ cat ~/.bash_profile |
验证maven版本
1 | bogon:~ jinglv$ mvn -v |
仓库配置
配置 Maven 本地仓库
在maven目录下:/maven-x.x./conf/settings.xml 中找到如下内容
1 | <localRepository>/path/to/local/repo</localRepository> |
把注释去掉改为自己本地的创建仓库的位置
localRepository 主要存放本地 jar 的缓存,如果本地有了就不去远程私服拉取,如果没有从私服拉,私服还没有从官网或者配置的阿里代理拉取。默认存放路径为:${user.home}/.m2/repository
mvn install 命令,可以把我们本地的项目自动打包成 jar,存放到上面的 jar 路径中。
运行命令mvn help:system
,当控制台出现 build success 时,创建仓库位置就会多了很多jar包
设置远程仓库
Maven 默认的远程地址是 http://my.repository.com/repo/path
这个是国外的地址,使用该地址下载会比较慢,一般我们用阿里云提供的地址替代。
打开 maven 解压的文件,找到 config 目录下面的 settings.xml 文件
在 settings.xml 文件中添加阿里云的地址,搜索到<mirrors>
位置
1 | <mirrors> |
检验刚才的配置是否生效,运行命令mvn help:system
,当控制台出现 build success 时,说明配置生效
Maven 常用的一些命令
创建 Maven 的普通 Java 项目:
1 | mvn archetype:create |
创建 Maven 的 Web 项目:
1 | mvn archetype:create |
编译项目:
1 | mvn compile |
运行测试:
1 | mvn test |
切换到 pom 文件根目录,对项目进行打包:
1 | mvn package |
如果有多个模块,针对其中一个模块进行打包,一般生产环境跳过单元测试,同时指定环境为 pro:
1 | mvn -pl 模块名 -am clean package -Dmaven.test.skip=true -P pro |
编译项目,并打包项目,同时会把 jar 安装到本地:
1 | mvn install |
清除 target 中的 class 文件、jar、配置文件等:
1 | mvn clean |
生成 eclipse 项目:
1 | mvn eclipse:eclipse |
生成 idea 项目:
1 | mvn idea:idea |
组合使用 goal 命令,如只打包不测试:
1 | mvn -Dtest package |
编译测试的内容:
1 | mvn test-compile |
只打 jar 包:
1 | mvn jar:jar |
只测试而不编译,也不测试编译:
1 | mvn test -skipping compile -skipping test-compile |
- -skipping 的灵活运用,当然也可以用于其他组合命令)
查看当前项目已被解析的依赖:
1 | mvn dependency:list |
上传到私服:
1 | mvn deploy |
强制检查更新,快照可能会经常更新,如果想强制更新就可以使用该命令:
1 | mvn clean install-U |
mvn compile、mvn install、mvn deploy,他们的主要区别如下:
- mvn compile,编译类文件
- mvn install,具有 mvn compile、mvn package 功能,把把 jar 安装到本地仓库
- mvn deploy,具有 mvn install 所有功能,如果配置了私服,会把打包后的 jar 上传到私服
Maven 对工程的拆分和聚合
工程拆分和聚合的思想
首先,为什么我们要把项目拆分,在最早我们做开发时,web/service/dao/html/css/config 等等,全部混合在一起,前端后端都维护一个项目,到后来我们做前后端分离。再到后来我们使用 mvc,分的越明细,分工也越明细,维护就越简单。而我们把公共的东西抽离出去,避免了重复造轮子的问题,很多公共的东西大家都可以重复使用,例如 date、http、md5 等常用工具类,一些公共业务逻辑可以放到 common-service,dao 层代码我们只需要一个人添加大家都可以公共等,拆分的思想让我们可以脚踩很多轮子,快速构建一个类似的工程。
例如之前我搭建了一个卖商标的商城,我把支付、在线聊天、用户系统等都拆分成一个个的 jar,半年后公司又转了业务要搭建一个做企业服务的商城,支付模块,在线聊天,用户系统等都是可以直接复用的,大大的减少了我们的开发成本。
其次,说到了拆分,必须就要提到聚合,拆分是为了代码可重用,而聚合就是我们构建一个完整的功能。这里的聚合不单单是说我们聚合成一个完整的项目,例如我在构建支付这个模块的时候,也把项目拆分为了 util/dao/service/三个模块,最终提供出去的就是 service 的几个方法支付、退款等,但是 util 中实现了我调第三方接口 http 的工具类、签名校验的工具类等,dao 层我实现了支付、退款记录保存到 db 功能,service 层实现具体的业务逻辑。但几个模块聚合到一起形成了一个完整的支付模块。
Maven的聚合思想
maven 在解决代码可重用和便于维护问题上是这么解决的: .
maven把一个完整的项目,分成不同的独立模块,这些模块都有各自独立的坐标,哪个地方需要其中某个模块,就直接引用该模块的坐标即可。
今后如果公司开发一个新项目,我们先考虑问题不是dao, service, utils, domain如何编写,我们要考虑的是,dao, service, utils, domain 这些模块是否已经存在,如果存在直接弓|用。
以上说的就是 maven 拆分的思想,我们可以把拆分零散的模块聚合到一起编写一个完整的项目 ,这就是maven聚合思想
聚合
如果我们想一次构建多个项目模块,那我们就需要对多个项目模块进行聚合。
例如:对项目的Hello、HelloFriend、MakeFriends这三个模块进行聚合
1 | <modules> |
继承
继承为了消除重复,我们把很多相同的配置提取出来,例如:grouptId,version等。
继承配置代码:
1
2
3
4
5
6<parent>
<groupId>me.gacl.maven</groupId>
<artifactId>ParentProject</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../ParentProject/pom.xml</relativePath>
</parent>
继承代码中定义属性:
1
2
3
4
5<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<junit.version>4.9</junit.version>
<maven.version>0.0.1-SNAPSHOT</maven.version>
</properties>
访问属性的方式为${junit.version}:
1
2
3
4
5
6<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
父模块用dependencyManagement进行管理:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17<dependencyManagement>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>cn.itcast.maven</groupId>
<artifactId>HelloFriend</artifactId>
<version>${maven.version}</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
</dependencies>
</dependencyManagement>