1. 简介
- 概念
- Maven的本质是一个项目管理工具,将项目开发和管理过程抽象成一个项目对象模型(POM)
- Maven是用Java语言编写的。他管理的东西统统以面向对象的形式进行设计,最终他把一个项目看成一个对象,而这个对象叫做POM(project object model),即项目对象模型
- Maven的作用
- 项目构建:提供标准的、跨平台的自动化项目构建方式
- 依赖管理:方便快捷的管理项目依赖的资源(jar包),避免资源间的版本冲突问题
- 统一开发结构:提供标准的、统一的项目结构如下
- 各目录存放资源类型说明
- src/main/java:项目java源码
- src/main/resources:项目的相关配置文件(比如mybatis配置,xml映射配置,自定义配置文件等)
- src/main/webapp:web资源(比如html,css,js等)
- src/test/java:测试代码
- src/test/resources:测试相关配置文件
- src/pom.xml:项目pom文件
2. 下载和安装
2.1 下载
- maven官网:http://maven.apache.org/
- 官方下载地址:http://maven.apache.org/download.cgi
2.2 安装
- 解压即安装
- 解压完成后目录结构如下
- 目录结构说明
- bin:可执行程序目录,
- boot:maven自身的启动加载器
- conf:maven配置文件的存放目录
- lib:maven运行所需库的存放目录
2.3 环境配置
- 我的电脑
-------->
属性--------->
高级系统设置---------->
新建系统变量MAVEN_HOME
,变量值为安装路径 - 配置path变量,新建
%MAVEN_HOME%\bin
3. 仓库
3.1 介绍
- 用于存储资源,包含各种jar包
3.2 分类
- 本地仓库:自己电脑上存储资源的仓库,连接远程仓库获取资源
- 远程仓库:
- 中央仓库:maven团队自身维护的仓库,属于开源的
- 私服:各公司/部门等小范围内存储资源的仓库,私服也可以从中央仓库获取资源
私服的作用
- 保存具有版权的资源,包含购买或自主研发的jar
- 一定范围内共享资源,能做到仅对内不对外开放
3.3 坐标
- Maven中的坐标用于描述仓库中资源的位置
- Maven坐标中主要组成
- groupId:定义当前资源隶属组织名称(通常是域名反写,如:org.mybatis;com.itheima)
- artifactId:定义当前资源的名称(通常是项目或模块名称,如:crm,sms)
- version:定义当前资源的版本号
packaging:定义资源的打包方式,取值一般有如下三种
- jar:该资源打成jar包,默认是jar
- war:该资源打成war包
- pom:该资源是一个父资源(表明使用maven分模块管理),打包时只生成一个pom.xml不生成jar或其他包结构
- 查询资源坐标
- 如果要查询maven某一个资源的坐标,我们通常可以去maven的仓库进行查询,在网站https://mvnrepository.com/中直接搜索想要的资源,点击进行查看
3.4 仓库配置
- 开发者要在自己电脑上做开发,首先要做的就是配置本地仓库
- 默认情况下maven本地仓库的位置,在maven的配置文件settings.xml中可以看到
<!-- localRepository | The path to the local repository maven will use to store artifacts. | | Default: ${user.home}/.m2/repository <localRepository>/path/to/local/repo</localRepository> -->
- 默认情况下,localRepository标签是在注释中的,将该标签挪出注释,修改其中的值,指定目录作为本地仓库的位置
- maven默认连接的远程仓库位置站点并不在国内,下载速度很慢,我们一般配置为国内的站点,例如
<mirror> <id>nexus-aliyun</id> <mirrorOf>central</mirrorOf> <name>Nexus aliyun</name> <url>http://maven.aliyun.com/nexus/content/groups/public</url> </mirror>
4. maven项目
4.1 Maven工程目录结构
4.2 手动搭建maven项目
- 在D盘下创建目录
mvnproject
并进入该目录,作为我们的操作目录 - 创建我们的maven项目,创建一个目录
project-java
作为我们的项目文件夹,并进入到该目录 - 创建java代码(源代码)所在目录,即创建
src/main/java
- 创建配置文件所在目录,即创建
src/main/resources
- 创建测试源代码所在目录,即创建
src/test/java
- 创建测试存放配置文件存放目录,即
src/test/resources
- 在
src/main/java
中创建一个包(注意在windos文件夹下就是创建目录)com/itheima
,在该目录下创建Demo.java
文件,作为演示所需java程序,内容如下package com.itheima; public class Demo{ public String say(String name){ System.out.println("hello "+name); return "hello "+name; } }
- 在
src/test/java
中创建一个测试包(目录)com/itheima
,在该包下创建测试程序DemoTest.java
package com.itheima; import org.junit.*; public class DemoTest{ @Test public void testSay(){ Demo d = new Demo(); String ret = d.say("maven"); Assert.assertEquals("hello maven",ret); } }
- 在
project-java/src
下创建pom.xml
文件,编辑如下<?xml version="1.0" encoding="UTF-8"?> <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/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.itheima</groupId> <artifactId>project-java</artifactId> <version>1.0</version> <packaging>jar</packaging> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency> </dependencies> </project>
- 通过前面的操作,我们已经搭建好了maven的项目结构,下面要通过maven来构建我们的项目
- 在项目
project-java
所在的DOS命令窗口下执行mvn compile
进行源码编译,当然首次执行需要先下载相关插件 - 编译完成后在项目
project-java
下多了一个目录target
,在这个目录下就存放的是maven编译好的一些东西,其中生成的classes
目录就是编译好的字节码文件 - 当然如果我们想清理掉这些东西,我们只需执行
mvn clean
命令即可,清理掉后target
目录也就消失了 - 如果我们要执行测试包中的测试程序,我们只需执行
mvn test
命令即可 - 此时在看
target
目录会多一些东西,其中产生的test-classes
就是测试代码的字节码文件,surefire-reports
是它产生的测试报告 - 使用
mvn package
命令进行打包,在生成的target
目录中可以看到打包的结果,当然,如果仔细看DOS窗口输出的我们会发现,mvn package
命令的时候maven会把前面两个命令mvn compile,mvn test
都执行一遍 - 使用
mvn install
命令进行安装,将项目打好的包存入本地仓库
- 在项目
4.3 IDEA工具搭建maven项目
- 1、在IDEA中配置Maven
- 2、创建maven工程
- 3、填写项目坐标
- 4、修改正确的目录颜色标记
- 5、IDEA右侧有maven管理界面,可以查看
- 6、在项目的pom.xml文件中添加项目资源依赖
- 7、创建源代码:com.itheima.Demo
package com.itheima;
/**
* Created by 传智播客*黑马程序员.
*/
public class Demo{
public String say(String name){
System.out.println("hello "+name);
return "hello "+name;
}
}
- 8、创建测试代码:com.itheima.DemoTest
package com.itheima;
import org.junit.Assert;
import org.junit.Test;
/**
* Created by 传智播客*黑马程序员.
*/
public class DemoTest{
@Test
public void testSay(){
Demo d = new Demo();
String ret = d.say("maven");
Assert.assertEquals("hello maven",ret);
}
}
- 9、测试运行
5. 依赖管理
- 所谓依赖管理就是maven对项目所有依赖资源的一种管理,它和项目之间是一种双向关系,即当我们做项目的时候maven的依赖管理可以帮助你去管理你所需要的其他资源,当其他的项目需要依赖我们项目的时候,maven也会把我们的项目当作一种资源去进行管理,这就是一种双向关系
- 依赖配置的格式如下
- 依赖传递
- 依赖具有传递性,分两种
- 直接依赖:在当前项目中通过依赖配置建立的依赖关系
- 间接依赖:被依赖的资源如果依赖其他资源,则表明当前项目间接依赖其他资源
注意
- 直接依赖和间接依赖其实也是一个相对关系
- 依赖具有传递性,分两种
- 在依赖传递中会产生冲突,我们有三种优先法则
- 路径优先:当依赖中出现相同资源时,层级越深,优先级越低,反之则越高
- 声明优先:当资源在相同层级被依赖时,配置顺序靠前的覆盖靠后的
- 特殊优先:当同级配置了相同资源的不同版本时,后配置的覆盖先配置的
- 可选依赖
- 可选依赖指对外隐藏当前所依赖的资源,不透明
<dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <optional>true</optional> </dependency>
- 排除依赖
- 排除依赖指主动断开依赖的资源,被排除的资源无需指定版本,不需要
<dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <exclusions> <exclusion> <groupId>org.hamcrest</groupId> <artifactId>hamcrest-core</artifactId> </exclusion> </exclusions> </dependency>
6. 依赖范围
- 依赖的jar默认情况可以在任何地方使用,可以通过scope标签设定其作用范围
- 作用范围
- 主程序范围有效(main文件夹范围内)
- 测试程序范围有效(test文件夹范围内)
- 是否参与打包(package指令范围内)
scope 主代码 测试代码 打包 范例 compile(默认) Y Y Y log4j test Y junit provided Y Y servlet-api runtime Y jdbc
- 依赖范围的传递性
- 带有依赖范围的资源在进行传递时,作用范围将受到影响
- 带有依赖范围的资源在进行传递时,作用范围将受到影响
7. Maven生命周期与插件
7.1 生命周期
- maven的构建生命周期描述的是一次构建过程经历了多少个事件,maven的生命周期总共分为3套,每套里面包含的事件如下
- clean:清理工作
- pre-clean:执行一些在clean之前的工作
- clean:移除上一次构建产生的所有文件
- post-clean:执行一些在clean之后立刻完成的工作
- default:核心工作,例如编译,测试,打包,部署等
- site:产生报告,发布站点等
- pre-site:执行一些在生成站点文档之前的工作
- site:生成项目的站点文档
- post-site:执行一些在生成站点文档之后完成的工作,为部署做准备
- site-deploy:将生成的站点文档部署到特定的服务器上
- clean:清理工作
注意
- 对于default生命周期,每个事件在执行之前都会将之前的所有事件依次执行一遍
7.2 插件
- maven生命周期中的相关事件是maven的插件来执行的
- 插件与生命周期内的阶段绑定,在执行到对应生命周期时执行对应的插件
- maven默认在各个生命周期上都绑定了预先设定的插件来完成相应功能
- 插件还可以完成一些自定义功能
- 插件的配置方式如下:
- 在maven官网中有对插件的介绍:http://maven.apache.org/plugins/index.html
8. Maven高级
8.1 分模块开发与设计
- 工业模块与模块划分
- ssm_pojo拆分
- 新建模块
- 拷贝原始项目中对应的相关内容到ssm_pojo模块中
- 实体类(User)
- ssm_dao拆分
- 新建模块
- 拷贝原始项目中对应的相关内容到ssm_dao 模块中
- 数据层接口(UserDao)
- 配置文件
- 保留与数据层相关配置文件(3个)
- 注意:分页插件在配置中与SqlSessionFactoryBean绑定,需要保留
- pom.xml:引入数据层相关坐标即可,删除springmvc相关坐标
- spring
- mybatis
- spring整合mybatis
- mysql
- druid
- pagehelper
- 直接依赖ssm_pojo(对ssm_pojo模块执行install指令,将其安装到本地仓库)
- ssm_service拆分
- 新建模块
- 拷贝原始项目中对应的相关内容到ssm_service模块中
- 业务层接口与实现类(UserService、UserServiceImpl)
- 配置文件:保留与数据层相关配置文件(1个)
- pom.xml:引入数据层相关坐标即可,删除springmvc相关坐标
- spring
- junit
- spring整合junit
- 直接依赖ssm_dao(对ssm_dao模块执行install指令,将其安装到本地仓库)
- 间接依赖ssm_pojo(由ssm_dao模块负责依赖关系的建立)
- 修改service模块spring核心配置文件名,添加模块名称,格式:applicationContext-service.xml
- 修改dao模块spring核心配置文件名,添加模块名称,格式:applicationContext-dao.xml
- 修改单元测试引入的配置文件名称,由单个文件修改为多个文件
- ssm_controller拆分
- 新建模块(使用webapp模块)
- 拷贝原始项目中对应的相关内容到ssm_controller模块中
- 表现层控制器类与相关设置类(UserController、异常相关…)
- 配置文件:保留与表现层相关配置文件(1个)、服务器相关配置文件(1个)
- pom.xml:引入数据层相关坐标即可,删除springmvc相关坐标
- spring
- springmvc
- jackson
- servlet
- tomcat服务器插件
- 直接依赖ssm_service(对ssm_service模块执行install指令,将其安装到本地仓库)
- 间接依赖ssm_dao、ssm_pojo
- 修改web.xml配置文件中加载spring环境的配置文件名称,使用
*
通配,加载所有applicationContext-开始的配置文件
总结
- 模块中仅包含当前模块对应的功能类与配置文件
- spring核心配置根据模块功能不同进行独立制作
- 当前模块所依赖的模块通过导入坐标的形式加入当前模块后才可以使用
- web.xml需要加载所有的spring核心配置文件
8.2 聚合
- 作用:聚合用于快速构建maven工程,一次性构建多个项目/模块。
- 制作方式
- 创建一个空模块,打包类型定义为pom
<packaging>pom</packaging>
- 定义当前模块进行构建操作时关联的其他模块名称
<modules> <module>../ssm_controller</module> <module>../ssm_service</module> <module>../ssm_dao</module> <module>../ssm_pojo</module> </modules>
- 创建一个空模块,打包类型定义为pom
- 模块的类型
- pom
- war
- jar
注意
- 参与聚合操作的模块最终执行顺序与模块间的依赖关系有关,与配置顺序无关
8.3 继承
- 作用
- 通过继承可以实现在子工程中沿用父工程中的配置
- maven中的继承与java中的继承相似,在子工程中配置继承关系
- 制作方式
- 在子工程中生命其父工程坐标与对应的位置
<!--定义该工程的父工程--> <parent> <groupId>com.itheima</groupId> <artifactId>ssm</artifactId> <version>1.0-SNAPSHOT</version> <!--填写父工程的pom文件--> <relativePath>../ssm/pom.xml</relativePath> </parent>
- 在父工程中定义依赖管理
<!--声明此处进行依赖管理--> <dependencyManagement> <!--具体的依赖--> <dependencies> <!--spring环境--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.1.9.RELEASE</version> </dependency> </dependencies> </dependencyManagement>
- 在子工程中定义依赖关系,无需声明依赖版本,版本参照父工程中依赖的版本
<dependencies> <!--spring环境--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> </dependency> </dependencies>
- 在子工程中生命其父工程坐标与对应的位置
- 继承的资源
- groupId:项目组ID,项目坐标的核心元素
- version:项目版本,项目坐标的核心元素
- description:项目的描述信息
- organization:项目的组织信息
- inceptionYear:项目的创始年份
- url:项目的URL地址
- developers:项目的开发者信息
- contributors:项目的贡献者信息
- distributionManagement:项目的部署配置
- issueManagement:项目的缺陷跟踪系统信息
- ciManagement:项目的持续集成系统信息
- scm:项目的版本控制系统信息
- malilingLists:项目的邮件列表信息
- properties:自定义的Maven属性
- dependencies:项目的依赖配置
- dependencyManagement:项目的依赖管理配置
- repositories:项目的仓库配置
- build:包括项目的源码目录配置、输出目录配置、插件配置、插件管理配置等
- reporting:包括项目的报告输出目录配置、报告插件配置等
- 继承与聚合
- 作用
- 聚合用于快速构建项目
- 继承用于快速配置
- 相同点
- 聚合与继承的pom.xml文件打包方式均为pom,可以将两种关系制作到同一个pom文件中
- 聚合与继承均属于设计型模块,并无实际的模块内容
- 不同点
- 聚合是在当前模块中配置关系,聚合可以感知到参与聚合的模块有哪些
- 继承是在子模块中配置关系,父模块无法感知哪些子模块继承了自己
- 作用
8.4 属性
- 为了版本统一
- 属性类别
- 自定义属性
- 内置属性
- Setting属性
- Java属性
- 环境变量属性
- 自定义属性
- 作用
- 等同于定义变量,方便统一维护
- 定义格式
<!--定义自定义属性--> <properties> <spring.version>5.1.9.RELEASE</spring.version> <junit.version>4.12</junit.version> </properties>
- 调用格式
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency>
- 作用
- 内置属性
- 作用
- 使用maven内置属性,快速配置
- 调用格式
${basedir} ${version}
- 作用
- Setting属性
- 作用
- 使用Maven配置文件setting.xml中的标签属性,用于动态配置
- 调用格式
${settings.localRepository}
- 作用
- Java系统属性
- 作用
- 读取Java系统属性
- 调用格式
${user.home}
- 系统属性查询方式
mvn help:system
- 作用
- 环境变量属性
- 作用
- 使用Maven配置文件setting.xml中的标签属性,用于动态配置
- 调用格式
${env.JAVA_HOME}
- 环境变量属性查询方式
mvn help:system
- 作用
8.5 版本管理
- 工程版本
- SNAPSHOT(快照版本)
- 项目开发过程中,为方便团队成员合作,解决模块间相互依赖和时间更新的问题,开发对每个模块进行构建的时候,输出的临时性版本叫快照版本(测试阶段版本)
- 快照版本会随着开发的进展不断更新
- RELEASE(发布版本)
- 项目开发到进入阶段里程碑后,向团队外部发布较为稳定的版本,这种版本所对应的构件文件是稳定的,即便进行功能的后续开发,也不会改变当前发布版本内容,这种版本称为发布版本
- SNAPSHOT(快照版本)
- 工程版本号约定
- 约定规范
- <主版本><次版本><增量版本><里程碑版本>
- 主版本:表示项目重大架构的变更
- 次版本:表示有较大的功能增加和变化,或者全面系统地修复漏洞
- 增量版本:表示有重大漏洞地修复
- 里程碑版本:表名一个版本的里程碑(版本内部)。这样的版本同下一个正式版本相比。相对来说很不稳定,有待更多的测试
- 约定规范
8.6 资源配置
- 配置文件引用pom属性
- 作用
- 在任意配置文件中加载pom文件中定义的属性
- 调用格式
${jdbc.url}
- 开启配置文件加载pom属性
<!--配置资源文件对应的信息--> <resources> <resource> <!--设定配置文件对应的位置目录,支持使用属性动态设定路径--> <directory>${project.basedir}/src/main/resources</directory> <!--开启对配置文件的资源加载过滤--> <filtering>true</filtering> </resource> </resources>
- 作用
8.7 多环境开发配置
- 多环境配置
<!--创建多环境--> <profiles> <!--定义具体的环境:生产环境--> <profile> <!--定义环境对应的唯一名称--> <id>pro_env</id> <!--定义环境中专用的属性值--> <properties> <jdbc.url>jdbc:mysql://127.1.1.1:3306/ssm_db</jdbc.url> </properties> <!--设置默认启动--> <activation> <activeByDefault>true</activeByDefault> </activation> </profile> <!--定义具体的环境:开发环境--> <profile> <id>dev_env</id> ... </profile> </profiles>
- 加载指定环境
- 作用
- 加载指定环境配置
- 调用格式
mvn 指令 -p 环境定义id
- 范例
mvn install -p pro_env
- 作用
8.8 跳过测试
- 跳过测试环节的应用场景
- 整体模块功能未开发
- 模块中某个功能未开发完毕
- 单个功能更新调试导致其他功能失败
- 快速打包
- …
- 使用命令跳过测试
- 命令
mvn 指令 -D skipTests
- 注意事项
- 执行的指令声明周期必须包含测试环节
- 命令
- 使用界面操作跳过测试
- 使用配置跳过测试
<plugin> <artifactId>maven-surefire-plugin</artifactId> <version>2.22.1</version> <configuration> <!--设置跳过测试--> <skipTests>true</skipTests> <!--包含指定的测试用例--> <includes> <include>**/User*Test.java</include> </includes> <!--排除指定的测试用例--> <excludes> <exclude>**/User*TestCase.java</exclude> </excludes> </configuration> </plugin>
8.9 私服
- Nexus
- Sonatype公司的一款maven私服产品
- 下载地址:https://help.sonatype.com/reponanager3/download
- 启动服务器(命令行启动)
nexus.exe /run nexus
- 访问服务器(默认端口:8081)
http://localhost:8081
- 修改基础配置信息
- 安装路径下etc目录中nexus-default.properties文件保存有nexus基础配置信息,例如默认访问端口
- 修改服务器运行配置信息
- 安装路径下bin目录中nexus.vmoptions文件保存有nexus服务器启动对应的配置信息,例如默认占用内存空间
- 私服资源获取
- 仓库分类
- 宿主仓库hosted
- 保存无法从中央仓库获取的资源
- 自主研发
- 第三方非开源项目
- 保存无法从中央仓库获取的资源
- 代理仓库proxy
- 代理远程仓库,通过nexus访问其他公共仓库,例如中央仓库
- 仓库组group
- 将若干个仓库组成一个群组,简化配置
- 仓库组不能保存资源,属于设计型仓库
- 宿主仓库hosted
- 上传资源时提供对应的信息
- 保存的位置(宿主仓库)
- 资源文件
- 对应坐标
- idea环境中资源上传与下载
- 访问私服配置(本地仓库访问私服)
- 配置本地仓库访问私服的权限(setting.xml)
<servers> <server> <id>release</id> <username>admin</username> <password>admin</password> </server> <server> <id>snapshots</id> <username>admin</username> <password>admin</password> </server> </servers>
- 配置本地仓库资源来源(setting.xml)
<mirrors> <mirror> <id>nexus</id> <mirrorOf>*</mirrorOf> <url>http://localhost:8081/repository/maven-public</url> </mirror> </mirrors>
- 配置当前项目访问私服上传资源的保存位置(pom.xml)
<distributionManagement> <repository> <id>release</id> <url>http://localhost:8081/repository/release</url> </repository> <snapshotRepository> <id>snapshots</id> <url>http://localhost:8081/repository/snapshots</url> </snapshotRepository> </distributionManagement>
- 发布资源到私服命令
mvn deploy
- 配置本地仓库访问私服的权限(setting.xml)