Maven
1. 分模块开发与设计
分模块开发步骤
- 创建maven模块
- 书写模块代码
- 分模块开发需要先针对模块功能进行设计,再进行编码。不能先将工程开发完毕再进行拆分
- 通过maven指令安装模块到本地仓库(install 指令)
- 团队内部开发需要发布模块功能到团队内部可共享的仓库中(私服)
2. 依赖管理
2.1 依赖传递与冲突问题
依赖传递
在项目所依赖jar包中,有的依赖前面有箭头>
,有的依赖前面没有;打开前面的箭头会发现这个jar包下面还包含有其他的jar包,并发现有两个相同的依赖被加载时,即便删去直接引用的依赖(第二个),程序也是可以正常运行的,这个特性就是依赖传递。
- 直接依赖:在当前项目中通过依赖配置建立的依赖关系
- 间接依赖:被依赖的资源如果依赖其他资源,当前项目间接依赖其他资源
冲突问题
- 路径优先:当依赖中出现相同的资源时,层级越深,优先级越低,层级越浅,优先级越高;
- 声明优先:当资源在相同层级被依赖时,配置顺序靠前的覆盖配置顺序靠后的;
- 特殊优先:当同级配置了相同资源的不同版本,后配置的覆盖先配置的
2.2 可选依赖和排除依赖
可选依赖
可选依赖指对外隐藏当前所依赖的资源——不透明
<dependency>
<groupId>com.wang</groupId>
<artifactId>maven_03_pojo</artifactId>
<version>1.0-SNAPSHOT</version>
<!--可选依赖是隐藏当前工程所依赖的资源,
隐藏后对应资源将不具有依赖传递性,
其它工程将无法引用 maven_03_pojo中的内容-->
<optional>true</optional>
</dependency>
排除依赖
排除依赖指主动断开依赖的资源,被排除的资源无需指定版本——不需要
<dependency>
<groupId>com.wang</groupId>
<artifactId>maven_04_dao</artifactId>
<version>1.0-SNAPSHOT</version>
<!--排除依赖是隐藏当前资源对应的依赖关系-->
<exclusions>
<exclusion>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
</exclusion>
</exclusions>
</dependency>
3. 聚合与继承
3.1 聚合
- 聚合:将多个模块组织成一个整体,同时进行项目构建的过程称为聚合;
- 聚合工程:通常是一个不具有业务功能的“空”工程(有且仅有一个pom文件)
- 作用:使用聚合工程可以将多个工程编组,通过对聚合工程进行构建,实现对所包含的模块进行同步构建(当工程中某个模块发生更新时,必须保障工程中与已更新模块关联的模块同步更新,此时可以使用聚合工程来解决批量模块同步构建的问题)
3.2 聚合工程开发
- 创建Maven模块,设置打包类型为pom
注:每个maven工程都有对应的打包方式,默认为jar,web工程打包方式为war<packaging>pom</packaging>
- 设置当前聚合工程所包含的子模块名称
注:聚合工程中所包含的模块在进行构建时会根据模块间的依赖关系设置构建顺序,与聚合工程中模块的配置书写位置无关;参与聚合的工程无法向上感知是否参与聚合,只能向下配置哪些模块参与本工程的聚合。<!--设置管理的模块名称--> <modules> <module>../maven_02_ssm</module> <module>../maven_03_pojo</module> <module>../maven_04_dao</module> </modules>
- 使用聚合统一管理项目
3.3 继承
- 概念:继承描述的是两个工程间的关系,与Java中的继承相似,子工程可以继承父工程中的配置信息,常见于依赖关系的继承
- 作用:简化配置;减少版本冲突
实现继承
- 创建Maven模块,设置打包类型为pom
注:建议父工程打包方式设置为pom<packaging>pom</packaging>
- 在父工程的pom文件中配置依赖关系(子工程将沿用父工程中的依赖关系)
<dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.2.10.RELEASE</version> </dependency> ...... </dependencies>
- 配置子工程中可选的依赖关系
<dependencyManagement> <dependencies> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.16</version> </dependency> ...... </dependencies> </dependencyManagement>
- 在子工程中配置当前工程所继承的父工程
<!--配置当前工程的父工程--> <parent> <groupId>com.wang</groupId> <artifactId>maven_parent</artifactId> <version>1.0-SNAPSHOT</version> <!--设置父项目pom.xml位置路径--> <relativePath>../maven_parent/pom.xml</relativePath> </parent>
- 在子工程中配置使用父工程中可选依赖的坐标
注:子工程中使用父工程中的可选依赖时,仅需要提供群组id和项目id,无需提供版本,版本由父工程统一提供,避免版本冲突;子工程中还可以定义父工程中没有定义的依赖关系。<dependencies> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> </dependency> </dependencies>
3.4 聚合和继承的区别
- 作用
- 聚合用于快速构建项目,对项目进行管理
- 继承用于快速配置和管理子项目中所使用jar包及版本
- 相同点
- 聚合与继承的pom.xml文件打包方式均为pom,可以将两种关系制作到同一个pom文件中
- 聚合与继承均属于设计型模块,并无实际的模块内容
- 不同点
- 聚合是在当前模块中配置关系,聚合可以感知到参与聚合的模块有哪些
- 继承是在子模块中配置关系,父模块无法感知哪些子模块继承了自己
4. 属性管理
4.1 属性
为便于管理工程中的依赖版本问题,通过properties标签定义变量实现对依赖版本进行统一管理。
- 定义属性
<!--定义自定义属性--> <properties> <spring.version>5.2.10.RELEASE</spring.version> <junit.version>4.12</junit.version> <mybatis-spring.version>1.3.0</mybatis-spring.version> </properties>
- 引用属性
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${spring.version}</version> </dependency>
4.2 配置文件加载属性
4.2.1 资源文件引用属性
-
定义属性
<!--定义自定义属性--> <properties> <spring.version>5.2.10.RELEASE</spring.version> <junit.version>4.12</junit.version> <jdbc.url>jdbc:mysql://127.0.0.1:3306/ssm_db</jdbc.url> </properties>
-
配置文件中引用属性
jdbc.driver=com.mysql.jdbc.Driver jdbc.url=${jdbc.url} jdbc.username=root jdbc.password=******
-
开启资源文件目录加载属性的过滤器
<bruid> <resources> <resource> <!--${project.basedir}: 当前项目所在目录,子项目继承了父项目, 相当于所有的子项目都添加了资源目录的过滤--> <directory>${project.basedir}/src/main/resources</directory> <filtering>true</filtering> </resource> </resources> </bruid>
-
配置maven打war包时,忽略web.xml的检查(不常用)
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <version>3.2.3</version> <configuration> <failOnMissingWebXml>false</failOnMissingWebXml> </configuration> </plugin> </plugins> </build>
4.2.2 maven中其他属性
属性分类 | 引用格式 | 实例 |
---|---|---|
自定义属性 | ${自定义属性名} | ${spring.version} |
内置属性 | ${内置属性名} | ${basedir} ${version} |
Setting属性 | ${setting.属性名} | ${setting.localRepository} |
Java系统属性 | ${系统属性分类.系统属性名} | ${user.home} |
环境变量属性 | ${env.环境变量属性名} | ${env.JAVA_HOME} |
- 在cmd命令行中输入
mvn help:system
查看这些属性
具体使用,就是使用${key}
来获取,key为等号左边的,值为等号右边的,比如获取选中内容的值,对应的写法为${java.runtime.name}
4.3 版本管理介绍
- 工程版本:
- SNAPSHOT(快照版本)
- 项目开发过程中临时输出的版本,称为快照版本
- 快照版本会随着开发的进展不断更新
- RELEASE(发布版本)
- 项目开发到进入阶段里程碑后,向团队外部发布较为稳定的版本,这种版本所对应的构建文件是稳定的,即便进行功能的后续开发,也不会改变当前发布版本的内容,这种版本称为发布版本
- SNAPSHOT(快照版本)
- 发布版本:
- alpha版:内测版,bug多不稳定内部版本不断添加新功能
- beta版:公测版,不稳定(比alpha稳定些),bug相对较多不断添加新功能
- 纯数字版
5. 多环境配置与应用
5.1 多环境开发
maven提供配置多种环境的设定,帮助开发者使用过程中快速切换环境。
-
父工程配置多个环境,并指定默认激活环境
<!--定义多环境--> <profiles> <!--定义具体的环境:生产环境--> <profile> <!--定义环境对应的唯一名称--> <id>env_dep</id> <!--定义环境中专用的属性值--> <properties> <jdbc.url>jdbc:mysql://127.0.0.1:3306/ssm_db</jdbc.url> </properties> <!--设定默认启动环境--> <activation> <activeByDefault>true</activeByDefault> </activation> </profile> <!--定义具体的环境:开发环境--> <profile> <id>env_pro</id> ...... </profile> </profiles>
-
执行安装查看env_dep环境是否生效
-
进行多环境切换(构建过程)
mvn 指令 -P 环境定义id mvn install -P env_pro // 范例
5.2 跳过测试
-
maven的UI界面中有按钮负责跳过测试,激活后即可跳过所有测试,缺点是无法自定义跳过的测试用例;
-
命令行跳过测试
mvn 指令 -D skipTests mvn install -D skipTests // 范例
注:执行的项目构建指令必须包含测试生命周期,否则无效果。例如执行compile生命周期时不经过test生命周期。
-
配置插件实现跳过测试
<!--细粒度控制跳过测试--> <build> <plugins> <plugin> <artifactId>maven-surefire-plugin</artifactId> <version>2.22.1</version> <configuration> <!--设置跳过测试--> <!--skipTests:如果为true,则跳过所有测试,如果为false,则不跳过测试 excludes:排除指定的测试用例,针对skipTests为false来设置的 includes: 包含指定的测试用例,针对skipTests为true来设置的--> <skipTests>false</skipTests> <!--排除指定的测试用例--> <excludes> <exclude>**/BookServiceTest.java</exclude> </excludes> </configuration> </plugin> </plugins> </build>
6. 私服
6.1 私服简介
私服是一台独立的服务器,用于解决团队内部的资源共享与资源同步问题。目前较为常用的私服产品为Nexus。
Nexus安装与启动
- 启动服务器 (命令行启动)
nexus.exe /run nexus
- 访问服务器(默认端口:8081)
http://localhost:8081
- 修改基础配置信息
- 安装路径下etc目录中nexus-default.properties文件保存有nexus基础配置信息,例如默认访问端口
- 修改服务器运行配置信息
- 安装路径下bin目录中nexus.vmoptions文件保存有nexus服务器启动对应的配置信息,例如默认占用内存空间
6.2 私服仓库分类
- 私服资源操作流程分析
- 在没有私服的情况下,本地项目创建的服务都安装在Maven的本地仓库中;
- 私服中也有仓库,项目资源上传到私服后最终也是放在私服的仓库中;
- 其他项目要想使用本项目所上传的资源,就需要从私服的仓库中获取;
- 当项目要使用的资源为远程中央仓库中的第三方jar包时,私服就会通过代理仓库来获取第三方jar包,第一次访问没有就会去远程中央仓库下载,下次再访问就直接走私服获取;
- 由于版本管理存在SNAPSHOT和RELEASE两类版本,将其都放到同一个仓库会比较混乱,因此私服会将这两种jar包放入不同的仓库;
- 为了方便获取,我们将所有的仓库编成一个组,我们只需要访问仓库组去获取资源。
仓库类别 | 英文名称 | 功能 | 关联操作 |
---|---|---|---|
宿主仓库 | hosted | 保存自主研发+第三档资源 | 上传 |
代理仓库 | proxy | 代理连接中央仓库 | 下载 |
仓库组 | group | 为仓库编组简化下载操作 | 下载 |
6.3 资源上传与下载
6.3.1 本地仓库访问私服配置
- 对私服的访问需要在本地Maven的配置文件settings.xml中进行配置。
- 在私服上配置仓库(进入私服的设置界面Repository-Repositories-Create repository,类型选maven2(hosted),snapshot仓库和release仓库都需要创建,最后记得保存)
- 配置本地Maven对私服的访问权限(找到Maven\apache-maven-3.6.2\conf下的setting.xml添加以下配置)
<servers> <server> <id>wang-snapshot</id> <username>admin</username> <password>******</password> </server> <server> <id>wang-release</id> <username>admin</username> <password>******</password> </server> </servers>
- 配置私服的访问路径
注:为了避免阿里云Maven私服地址的影响,建议先将之前配置的阿里云Maven私服镜像地址注释掉,等练习完后再将其恢复。<mirrors> <mirror> <!--配置仓库组的ID--> <id>maven-public</id> <!--*代表所有内容都从私服获取--> <mirrorOf>*</mirrorOf> <!--私服仓库组maven-public的访问路径--> <url>http://localhost:8081/repository/maven-public/</url> </mirror> </mirrors>
- 至此本地仓库就能与私服进行交互了。
6.3.2 资源上传与下载
工程上传到私服服务器设置
-
配置位置(工程pom文件中)
<!--配置当前工程保存在私服中的具体位置--> <distributionManagement> <repository> <!--和maven/settings.xml中server中的id一致,表示使用该id对应的用户名和密码--> <id>wang-release</id> <!--release版本上传仓库的具体地址--> <url>http://localhost:8081/repository/wang-release/</url> </repository> <snapshotRepository> <!--和maven/settings.xml中server中的id一致,表示使用该id对应的用户名和密码--> <id>wang-snapshot</id> <!--snapshot版本上传仓库的具体地址--> <url>http://localhost:8081/repository/wang-snapshot/</url> </snapshotRepository> </distributionManagement>
-
发布命令
mvn deploy
注:要发布的项目都需要配置
distributionManagement
标签,要么在自己的pom.xml中配置,要么在其父项目中配置,然后子项目中继承父项目即可。
资源上传的位置与GAV中version的后缀有关,SNAPSHOT版本后缀的项目打包至wang-snapshot仓库中,RELEASE版本后缀的项目打包至wang-release仓库中。