Maven 简介
传统项目管理的缺点:
(1) jar 包不统一,jar 包不兼容;
(2) 工程升级维护过程操作繁琐;
Maven 是什么
Maven 的本质是一个项目管理工具,将项目开发和管理过程抽象成一个项目对象模型 (POM)
POM (Project Object Model) : 项目对象模型
Maven 的作用
- 项目构建:提供标准的跨平台的自动化项目构建方式;
- 依赖管理:方便快捷地管理项目依赖的资源 (jar 包), 避免资源间的版本冲突问题。
- 统一开发结构: 提供标准的、统一的项目结构
Maven 的下载与安装
下载地址
Maven 属于绿色版软件,解压即安装。
bin 目录:核心运行文件;
boot 目录: 类加载器;
conf 目录:核心配置;
lib 目录:所依赖的 jar 包;
Maven 环境变量配置
Path 里添加:
配置成功:
Maven 基本概念
仓库:用于存储资源,包含各种 jar 包
仓库分类:
(1) 本地仓库:自己电脑上存储资源的仓库,连接远程仓库获取资源;
(2) 远程仓库:非本机电脑上的仓库,为本地仓库提供资源
① 中央仓库:Maven 团队维护,存储所有资源的仓库;
② 私服:部门/公司范围内存储资源的仓库,从中央仓库获取资源;
私服的作用:
① 保存具有版权的资源,包含购买或自主研发的 jar;
② 解决访问速度慢的问题;
坐标:描述仓库中资源的位置
组成:
groupId: 定义当前 Maven 项目隶属的组织名称(通常是域名反写,如 org.mybatis) ;
artifactId: 定义当前 Maven 项目名称(通常是模块名称,例如 CRM, SMS)
version: 定义当前项目版本号;
packaging: 定义当前项目的版本号;
https://mvnrepository.com/
本地仓库配置
Maven 启动后,会自动保存下载的资源到本地仓库;
conf 下 settings.xml 中:
默认位置:
<localRepository>${user.home}/.m2/repository</localRepository>
自定义位置:
<localRepository>D:\maven\repository</localRepository>
远程仓库配置
lib 下 maven-model-builder-3.6.1.jar 下的 pom-4.0.0.xml
访问速度慢:
<repositories>
<repository>
<id>central</id>
<name>Central Repository</name>
<url>https://repo.maven.apache.org/maven2</url>
<layout>default</layout>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
镜像仓库配置
在 settings.xml 中配置阿里云镜像仓库:
<mirrors>
<!-- 配置具体仓库下的镜像文件 -->
<mirror>
<!-- 此镜像的唯一标识符,用来区分不同 mirror 元素 -->
<id>nexus-aliyun</id>
<!-- 对哪个仓库进行镜像,简单来说就是要替换哪个仓库 -->
<mirrorOf>central</mirrorOf>
<!-- 镜像名称 -->
<name>Nexus aliyun</name>
<!-- 镜像 URL -->
<url>http://maven.aliyun.com/nexus/content/groups/public</url>
</mirror>
</mirrors>
第一个 Maven 项目(手工制作)
Maven 工程目录结构
在 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.weixinyang</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 构建命令使用 mvn 开头,后面添加功能参数,可以一次执行多个命令,使用空格分隔。
mvn compile #编译
mvn clean #清理
mvn test #测试 target 目录下 surefire-reports 有测试报告
mvn package #打包 只打包源程序
mvn install #安装到本地仓库
插件创建工程
(注意要用 命令行,不要用 powershell)
格式:
mvn archetype:generate
-DgroupId={project-packaging}
-DartifactId={project-name}
-DarchetypeArtifactId=maven-archetype-quickstart
-DinteractiveMode=false
创建 java 工程:
mvn archetype:generate -DgroupId=com.weixinyang -DartifactId=java-project
-DarchetypeArtifactId=maven-archetype-quickstart -Dversion=0.0.1-snapshot
-DinteractiveMode=false
创建 web 工程:
mvn archetype:generate -DgroupId=com.weixinyang -DartifactId=web-project
-DarchetypeArtifactId=maven-archetype-webapp -Dversion=0.0.1-snapshot
-DinteractiveMode=false
Maven 工程目录结构:
第一个 Maven 项目(Idea 生成)
Maven 环境配置
Java 项目创建(手工创建)
① 点击右上角
②
③
④ 设置目录属性
或者
右边的 Maven 管理工具,添加依赖后要刷新
Maven 命令执行
方法 1:
方法 2:
compile 后会生成 target 目录:
Java 项目创建(原型创建)
没有 resources
Web 项目创建(原型创建)
添加和修改目录结构:
Tomcat 7 插件运行 web 项目
<build>
<!--设置插件-->
<plugins>
<!--具体的插件设置-->
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.1</version>
<configuration>
<port>80</port>
<path>/</path>
</configuration>
</plugin>
</plugins>
</build>
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">
<!--指定 pom 的模型版本-->
<modelVersion>4.0.0</modelVersion>
<!--打包方式,web 工程打包为 war, java 工程打包为 jar-->
<packaging>war</packaging>
<name>web01</name>
<!--组织 id-->
<groupId>com.weixinyang</groupId>
<!--项目 id-->
<artifactId>web01</artifactId>
<!--版本号 release(完成版), snapshot(开发版)-->
<version>1.0-SNAPSHOT</version>
<!--设置当前工程的所有依赖-->
<dependencies>
<!--具体的依赖-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
<!--构建-->
<build>
<!--设置插件-->
<plugins>
<!--具体的插件设置-->
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.1</version>
<configuration>
<port>80</port>
<path>/</path>
</configuration>
</plugin>
</plugins>
</build>
</project>
依赖管理
依赖配置
依赖指当前项目运行所需要的 jar, 一个项目可以设置多个依赖。
<!-- 设置当前项目所需要的所有 jar-->
<dependencies>
<!-- 设置具体的依赖 -->
<dependency>
<!-- 依赖所属群组 id-->
<groupId>junit</groupId>
<!-- 依赖所属项目 id-->
<artifactId>junit</artifactId>
<!-- 依赖版本号 -->
<version>4.12</version>
</dependency>
</dependencies>
依赖传递
依赖具有传递性:
- 直接依赖:在当前项目中通过依赖配置建立的依赖关系;
- 间接依赖:被依赖资源如果依赖其他资源,当前项目间接依赖其他资源;
依赖传递的冲突问题
- 路径优先:当依赖中出现相同的资源时,层级越浅,优先级越高,层级越深,优先级越低;
- 声明优先:当资源在相同层级被依赖时,配置顺序靠前的覆盖配置顺序靠后的;
- 特殊优先:当同级配置了相同资源的不同版本,后配置的覆盖先配置的;
可选依赖(不透明)
可选依赖指对外隐藏当前所依赖的资源 - 不透明
<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>
依赖范围
- 依赖的 jar 默认情况可以在任何地方使用,可以通过 scope 标签设定其作用范围
- 作用范围
- 主程序范围内有效 (main 文件夹范围内)
- 测试程序范围内有效(test 文件夹范围内)
- 是否参与打包(package 指令范围内)
依赖范围传递性
带有依赖范围的资源在进行传递时,作用范围会受到影响:
生命周期与插件
项目构建生命周期
Maven 构建生命周期描述的是一次构建过程中经历了多少个事件:
- Maven 对项目构建的生命周期划分为三套:
- clean: 清理工作
- default: 核心工作,例如编译、测试、打包、部署等
- site: 产生报告,发布站点等
clean 构建生命周期
- pre-clean 执行一些需要在clean之前完成的工作
- clean 移除所有上一次构建生成的文件
- post-clean 执行一些需要在clean之后立刻完成的工作
default 构建生命周期
- validate(校验) 校验项目是否正确并且所有必要的信息可以完成项目的构建过程。
- initialize(初始化) 初始化构建状态,比如设置属性值。
- generate-sources(生成源代码) 生成包含在编译阶段中的任何源代码。
- process-sources(处理源代码) 处理源代码,比如说,过滤任意值。
- generate-resources(生成资源文件) 生成将会包含在项目包中的资源文件。
- process-resources (处理资源文件) 复制和处理资源到目标目录,为打包阶段最好准备。
- compile(编译) 编译项目的源代码。
- process-classes(处理类文件) 处理编译生成的文件,比如说对Java class文件做字节码改善优化。
- generate-test-sources(生成测试源代码) 生成包含在编译阶段中的任何测试源代码。
- process-test-sources(处理测试源代码) 处理测试源代码,比如说,过滤任意值。
- generate-test-resources(生成测试资源文件) 为测试创建资源文件。
- process-test-resources(处理测试资源文件) 复制和处理测试资源到目标目录。
- test-compile(编译测试源码) 编译测试源代码到测试目标目录.
- process-test-classes(处理测试类文件) 处理测试源码编译生成的文件。
- test(测试) 使用合适的单元测试框架运行测试(Juint是其中之一)。
- prepare-package(准备打包) 在实际打包之前,执行任何的必要的操作为打包做准备。
- package(打包) 将编译后的代码打包成可分发格式的文件,比如JAR、 WAR或者EAR文件。
- pre-integration-test(集成测试前) 在执行集成测试前进行必要的动作。比如说,搭建需要的环境。
- integration-test(集成测试) 处理和部署项目到可以运行集成测试环境中。
- post-integration-test(集成测试后) 在执行集成测试完成后进行必要的动作。比如说,清理集成测试环境。
- verify (验证) 运行任意的检查来验证项目包有效且达到质量标准。
- install(安装) 安装项目包到本地仓库,这样项目包可以用作其他本地项目的依赖。
- deploy(部署) 将最终的项目包复制到远程仓库中与其他开发者和项目共享。
site 构建生命周期
- pre-site 执行一些需要在生成站点文档之前完成的工作
- site 生成项目的站点文档
- post-site 执行一些需要在生成站点文档之后完成的工作,并且为部署做准备
- site-deploy 将生成的站点文档部署到特定的服务器上
插件
- 插件与生命周期内的阶段绑定,在执行到对应生命周期时执行对应的插件功能
- 默认 maven 在各个生命周期上绑定有预设的功能
- 通过插件可以自定义其他功能
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.2.1</version>
<executions>
<execution>
<goals>
<goal>jar</goal>
</goals>
<phase>generate-test-resources</phase>
</execution>
</executions>
</plugin>
</plugins>
</build>
分模块开发与设计
工程模块与模块划分
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 核心配置文件
聚合
多模块构建维护
聚合
- 作用:聚合用于快速构建 maven 工程,一次性构建多个项目/模块。
- 制作方式:
(1) 创建一个空模块,打包类型定义为 pom
<packaging>pom</packaging>
(2) 定义当前模块进行构建操作时关联的其他模块名称
<modules>
<module>../ssm_controller</module>
<module>../ssm_service</module>
<module>../ssm_dao</module>
<module>../ssm_pojo</module>
</modules>
注意事项:参与聚合操作的模块最终执行顺序与模块间的依赖关系有关,与配置顺序无关;
继承
继承
- 作用:通过继承可以实现在子工程中沿用父工程中的 配置
- maven 中的继承与 java 中的继承相似,在子工程中配置继承关系
继承依赖定义
- 在父工程中定义依赖管理
<!-- 声明此处进行依赖管理 -->
<dependencyManagement>
<!-- 具体的依赖 -->
<dependencies>
<!-- spring 环境 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.9.RELEASE</version>
</dependency>
<dependencies>
<dependencyManagement>
继承依赖使用
- 在子工程中声明其父工程坐标与对应的位置
<!--定义该工程的父工程-->
<parent>
<groupId>com.weixinyang</groupId>
<artifactId>ssm</artifactId>
<version>1.0-SNAPSHOT</version>
<!-- 填写父工程的 pom 文件 -->
<relativePath>../ssm/pom.xml</relativePath>
</parent>
- 在子工程中定义依赖关系,无需声明依赖版本,版本参照父工程中依赖的版本
<dependencies>
<!-- spring 环境 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
</dependencies>
继承的资源
继承与聚合
- 作用
- 聚合用于快速构建项目
- 继承用于快速配置
- 相同点
- 聚合与继承 的 pom.xml 文件打包方式均为 pom,可以将两种关系制作到同一个 pom 文件中
- 聚合与继承 均属于 设计型模块,并无实际模块内容
- 不同点
- 聚合是在当前模块中配置关系,聚合可以感知到参与聚合的模块有哪些
- 继承是在子模块中配置关系,父模块无法感知哪些子模块继承了自己
属性
自定义属性
- 作用:等同于定义变量,方便统一维护
- 定义格式:
<!--定义自定义属性-->
<properties>
<spring.version>5.1.9.RELEASE</spring.version>
<junit.version>4.12</junit.version>
</properties>
- 调用格式
<version>${spring.version}</version>
内置属性
- 作用:使用 maven 内置属性,快速配置
- 调用格式:
${basedir}
${version}
Setting 属性
- 作用:使用 maven 配置文件 settings.xml 中的标签属性,用于动态配置
- 调用格式
${settings.localRepository}
Java 系统属性
- 作用
- 读取 Java 系统属性
- 调用格式
${user.home}
- 系统属性查询方式
mvn help:system
环境变量属性
- 调用格式
${env.JAVA_HOME}
- 环境变量属性查询方式
mvn help:system
版本管理
工程版本
- SNAPSHOT (快照版本)
- 项目开发过程中,为方便团队成员合作,解决模块间相互依赖和不时更新的问题,开发者对每个模块进行构建的时候,输出的临时性版本叫快照版本(测试阶段版本)
- 快照版本会随着开发的进展不断更新
- RELEASE (发布版本)
- 项目开发进入阶段里程碑后,向团队外部发布较为稳定的版本,这种版本所对应的构件文件是稳定的,即便进行功能的后续开发,也不会改变当前发布版本内容,这种版本称为发布版本
工程版本号约定
- 约定规范
- <主版本>.<次版本>.<增量版本>.<里程碑版本>
- 主版本:表示项目重大架构的变更,如: spring 5 相较于 spring 4 的迭代
- 次版本:表示有较大的功能增加和变化,或者全面系统地修复漏洞
- 增量版本:表示有重大漏洞的修复
- 里程碑版本:表明一个版本的里程碑(版本内部)。这样的版本
- 范例
- 5.1.9.RELEASE
资源配置
资源配置多文件维护
配置文件引用 pom 属性
- 作用:在任意配置文件中加载 pom 文件中定义的属性
- 调用格式
${jdbc.url}
- 开启配置文件加载 pom 属性
<!-- 配置资源文件对应的信息 -->
<resources>
<resource>
<!-- 设定配置文件对应的位置目录,支持使用属性动态设定路径 -->
<directory>${project.basedir}/src/main/resources</directory>
<!-- 开启对配置文件的资源加载过滤 -->
<filtering>true</filtering>
</resource>
</resources>
<!--配置测试资源文件对应的信息-->
<testResources>
<testResource>
<directory>${project.basedir}/src/test/resources</directory>
<filtering>true</filtering>
</testResource>
</testResources>
多环境开发配置
多环境兼容
多环境配置
<!--创建多环境-->
<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>dep_env</id>
<properties>
<jdbc.url>jdbc:mysql://127.2.2.2:3306/ssm_db</jdbc.url>
</properties>
</profile>
</profiles>
加载指定环境
- 作用:加载指定环境配置
- 调用格式
mvn 指令 -P 环境定义id
例如:
mvn install –P pro_env
跳过测试
使用命令跳过测试
- 命令
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>
私服
分模块合作开发
Nexus
- Nexus 是 Sonatype 公司的一款 maven 私服产品
- 下载地址:https://help.sonatype.com/repomanager3/download
Nexus 安装、启动与配置
- 启动服务器(命令行启动)
nexus /run nexus
- 访问服务器(默认端口:8081)
http://localhost:8081
- 修改基础配置信息
- 安装路径下 etc 目录中 nexus-default.properties 文件保存有 nexus 基础配置信息,例如默认访问端口
- 修改服务器运行配置信息
- 安装路径下 bin 目录中 nexus.vmoptions 文件保存有 nexus 服务器启动对应的配置信息,例如默认占用内存空间
私服资源获取
仓库分类
- 宿主仓库 hosted
- 保存无法从中央仓库获取的资源
- 自主研发
- 第三方非开源项目
- 保存无法从中央仓库获取的资源
- 代理仓库 proxy
- 代理远程仓库,通过 nexus 访问其他公共仓库,例如中央仓库
- 仓库组 group
- 将若干个仓库组成一个群组,简化配置
- 仓库组不能保存资源,属于设计型仓库
资源上传
idea 环境下资源上传与下载
访问私服配置(本地仓库访问私服)
- 配置本地仓库访问私服的权限 (settings.xml)
<!--配置访问服务器的权限,用户名密码-->
<servers>
<server>
<id>weixinyang-release</id>
<username>admin</username>
<password>admin</password>
</server>
<server>
<id>weixinyang-snapshot</id>
<username>admin</username>
<password>admin</password>
</server>
</servers>
- 配置本地仓库资源来源 (settings.xml)
<mirrors>
<mirror>
<id>nexus-aliyun</id>
<mirrorOf>central</mirrorOf>
<name>Nexus aliyun</name>
<url>http://maven.aliyun.com/nexus/content/groups/public</url>
</mirror>
<!--自定义的 weixinyang 私服-->
<mirror>
<id>nexus-weixinyang</id>
<mirrorOf>*</mirrorOf>
<url>http://localhost:8081/repository/maven-public/</url>
</mirror>
</mirrors>
访问私服配置(项目工程访问私服)
- 配置当前项目访问私服上传资源的保存位置 (pom.xml)
<!--发布配置管理-->
<distributionManagement>
<repository>
<id>weixinyang-release</id>
<url>http://localhost:8081/repository/weixinyang-release/</url>
</repository>
<snapshotRepository>
<id>weixinyang-snapshot</id>
<url>http://localhost:8081/repository/weixinyang-snapshot/</url>
</snapshotRepository>
</distributionManagement>
- 发布资源到私服命令
mvn deploy