1.分模块开发
1.分模块开发意义
我们写一个项目都喜欢写在一个模块中,就比如SSM 整合开发,将所有业务功能集中一起开发,会存在一些问题:
- 当其中一个功能出现问题,会导致整个项目无法正常启动,从而等导致其他正常的功能无法工作
- 项目的维护成本比较高
- 代码可能会出现重复的问题
将原始模块按照功能拆分成若干个子模块,达到分模块开发:
- 就能方便模块间的相互调用,接口共享
- 项目中每个功能都可以单独维护,从而降低了解耦合
- 可以很方便的被别人使用
2.分模块开发
分模块开发设计
根据项目的业务功能拆分
将项目的每一层(controller、service、dao、pojo)分模块拆分出来根据项目的业务模块拆分
将项目的每一个业务功能分模块进行开发,例如电商系统中的订单模块单独抽取出来,商品模块抽取出来
分模块开发案例
基于 SSM 整合的项目实现分模块开发
例如:将 pojo (实体类)层独立开发
创建新模块
将 ssm_demo 中的 pojo 拷贝到 ssm_pojo 中,并删除 ssm_demo 中的 pojo
然后发现:ssm_demo中用到的实体类对象都爆红,因为实体类已经没有了
因此需要在 ssm_demo 中添加 ssm_pojo 的依赖
- 将 ssm_pojo 的依赖 下载到 maven本地仓库 中
使用maven的install命令,把其安装到Maven的本地仓库中
在 ssm_demo 项目的 pom.xml 添加 ssm_pojo 的依赖
<dependency> <groupId>com.maoge</groupId> <artifactId>ssm_pojo</artifactId> <version>1.0-SNAPSHOT</version> </dependency>
注意:如果没有做第三步,即使添加了依赖,依然还是报错,原因是Maven会从本地仓库找对应的jar包,但是本地仓库又不存在该jar包所以会报错
- 执行 ssm_demo 的compile(编译)
至于其他层的分模块开发,家人们可以线下自己尝试去试试,与上雷同
2.依赖管理
依赖:指当前项目运行所需要的jar包,一个项目可以设置多个依赖
格式:
<!--设计当前项目所依赖的所有jar--> <dependencies> <!--设置具体的依赖--> <dependency> <!--依赖所属群组id--> <groupId>junit</groupId> <!--依赖所属项目id--> <artifactId>junit</artifactId> <!--依赖版本号--> <version>4.12</version> <!--依赖的作用域--> <scope>test</scope> </dependency> </dependencies>
1.依赖传递
- 依赖具有传递性
- 直接依赖:在当前项目中通过依赖配置建立的依赖关系。
- 间接依赖:被依赖的资源还依赖其他资源,则当前项目间接依赖其他资源。(举例:A依赖B,B依赖C,所以A间接也依赖C)
依赖传递冲突
依赖冲突:一个项目中导入了多个不同版本的同名包,那么就产生了冲突。这个冲突很有可能导致项目无法运行。
举例:
基于依赖传递出现的冲突问题,maven提供了三种处理情况
- 当同级中配置了相同资源的不同版本,后配置的覆盖前面配置的
- 当依赖中出现相同资源时,层级越深,优先级越低;层级越浅,优先级越高
- 当被依赖的资源在相同层级时,配置顺序靠前的覆盖配置顺序靠后的
2.可选依赖
可选依赖:指对外隐藏当前所依赖的资源
举例:
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.16</version>
<!--可选依赖是隐藏当前工程所依赖的资源,隐藏后对应资源不具有依赖传递性-->
<optional>true</optional>
</dependency>
3.排除依赖
排除依赖:指主动断开依赖的资源,被排除的资源无需指定版本
举例:
<dependency>
<groupId>com.maoge</groupId>
<artifactId>maven_03_dao</artifactId>
<version>1.0-SNAPSHOT</version>
<!--排除当前资源对应的依赖关系-->
<exclusions>
<!--将当前资源中多的log4j排除掉-->
<exclusion>
<artifactId>log4j</artifactId>
<groupId>log4j</groupId>
</exclusion>
</exclusions>
</dependency>
注意:排除依赖仅指定GA即可,无需指定V
3.聚合与继承
1.聚合
- 聚合:将多个模块组织成一个整体,同时进行项目构建的过程称为聚合
- 聚合工程:通常是一个不具有业务功能的 “空工程”(有且仅有一个pom文件)
- 作用:使用聚合工程可以将多个工程编组,通过对聚合工程进行构建,实现对所包含的模块进行同步构建
- 好处:当工程中某个模块发生更新时,必须保障工程中与已更新模块关联的模块同步更新
- 好处:当工程中某个模块发生更新时,必须保障工程中与已更新模块关联的模块同步更新
聚合工程开发:
1.创建Maven模块,设置打包类型为pom
<packaging>pom</packaging>
2.设置当前聚合工程所包含的子模块名称
举例:
<modules>
<module>../ssm_demo</module>
<module>../ssm_pojo</module>
</modules>
注意:
1.聚合工程所包含的模块在进行构建时会根据模块间的依赖关系设置构建顺序,与聚合工程中模块的配置书写位置无关
2.参与聚合的工程无法向上感知是否参与聚合,只能向下配置哪些模块参与本工程的聚合
2.继承
继承:继承描述的是两个工程间的关系,与java中的继承相似,子工程可以继承父工程的配置信息,常见于依赖关系的继承。
作用:
- 简化配置
- 减少版本冲突
继承关系配置:
1.创建Maven模块为父工程,设置打包方式为pom
<packaging>pom</packaging>
2.在父工程的pom文件配置依赖关系
<dependencies>
<!--父工程中配置的依赖,子工程都会被继承 -->
</dependencies>
注意:子工程会沿用父工程中的依赖关系
3.父工程中配置子工程中可选的依赖关系
<dependencyManagement>
<!--配置子工程的可选依赖 -->
<!--子工程只需在自己pom中导入GA,无需导入V(第五步) -->
</dependencyManagement>
4.在子工程配置当前工程所继承的父工程
<!--定义该工程的父工程 -->
<parent>
<groupId>com.maoge</groupId>
<artifactId>ssm_parent</artifactId>
<version>1.0-SNAPSHOT</version>
<!--填写父工程的pom文件-->
<relativePath>../ssm_parent/pom.xml</relativePath>
</parent>
5.在子工程中配置使用父工程中可选依赖的坐标
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
</dependency>
注意:
1.子工程使用父工程中的可选依赖时,仅提供群组id和项目id,无需提供版本,版本由父工程统一管理,避免版本冲突
2.子工程中还可以定义父工程中没有定义的依赖关系
3.扩展:聚合与继承的区别
- 作用
- 聚合用于快速构建项目
- 继承用于快速配置
- 相同点
- 聚合与继承的pom.xml文件打包方式均为pom,所以可以将两种关系制作到同一个pom文件中
- 聚合与继承均属于设计型模块,并无实际的模块内容
- 不同点
- 聚合是在当前模块中配置关系,聚合可以感知到参与聚合的模块有哪些
- 继承是在子模块的配置关系,父模块无法感知子模块继承了自己
4.属性管理
1.属性配置
定义属性
<!-- s--> <properties> <spring-version>5.2.10.RELEASE</spring-version> </properties>
引用属性
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>${spring-version}</version> </dependency>
扩展
资源文件引用属性(案例)
定义属性
<properties> <jdbc-url>jdbc:mysql:///ssm_db</jdbc-url> </properties>
配置文件中引用属性
jdbc.driverClass=com.mysql.cj.jdbc.Driver jdbc.url=${jdbc-url} jdbc.username=root jdbc.password=root
开启资源文件目录加载属性的过滤器
<build> <resources> <resource> <directory>${project.basedir}/src/main/resources</directory> <filtering>true</filtering> </resource> </resources> </build>
其他属性(了解)
2.版本管理
工程版本
- SNAPSHOT(快照版本)
- 项目开发工程中临时输出的版本,称为快照版本
- 快照版本会随着开发的进展不断更新
- RELEASE(发布版本)
- 项目开发到进入阶段里程碑后,向团队外部发布较为稳定的版本,这种版本所对应的构建文件是稳定的,即便进行功能的后续开发,也不会改变当前发布版本内容,这种版本称为发布版本。
其他发布版本:
- alpha版
- beta版
- 纯数字版
5.多环境开发
项目开发通常会有三种环境:
- 开发环境
- 生产环境
- 测试环境
为了能够根据不同的环境采用不同的配置,Maven提供了多环境开发模式
多环境配置
定义多环境
<!--定义多环境--> <profiles> <!--定义生产环境--> <profile> <!--定义环境对应的唯一名称--> <id>env_dep</id> <!--定义环境中专用的属性值--> <properties> <jdbc-url>jdbc:mysql:///ssm_db</jdbc-url> </properties> <!--设置默认启动--> <activation> <activeByDefault>true</activeByDefault> </activation> </profile> <!--定义开发环境--> <profile> <id>env_dep</id> ...... </profile> </profiles>
- 使用多环境
使用命令行:mvn 指令 -P 环境定义id
举例:
mvn install -P env_dep
跳过测试
由于执行maven的指令会根据maven生命周期,包括执行指令之前的所有环节,比如package 和 install 都包含了 test环节。
但有时我们想跳过test环节,直接进行后面的环节
1.使用命令行
mvn install -D skipTests
注意:执行的项目构建指令必须包含测试生命周期,否则无效果。例如:compile的生命周期不经过test生命周期
2.pom文件
pom文件配置可以控制跳过测试的细粒度,更加精确高效
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
<configuration>
<!--设置跳过测试-->
<skip>true</skip>
<!--包含指定的测试用例-->
<includes>
<include>**/Book*Test.java</include>
</includes>
<!--排除指定的测试用例-->
<excludes>
<exclude>**/User*Test.java</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
3.IDEA
IDEA的右菜单栏上maven图标中的闪电按钮点击即可跳过test环节
6.私服
私服简介
私服是一种特殊的远程仓库,它是架设在局域网内的仓库服务,用来代理位于外部的远程仓库
Maven私服搭建后,当局域网内的用户需要某个构件时,会按照如下顺序:
- 请求本地仓库,若本地仓库不存在所需构件,则跳转到第 2 步;
- 请求 Maven 私服,将所需构件下载到本地仓库,若私服中不存在所需构件,则跳转到第 3 步。
- 请求外部的远程仓库,将所需构件下载并缓存到 Maven 私服,若外部远程仓库不存在所需构件,则 Maven 直接报错。
私服搭建
能够帮助我们建立 Maven 私服的软件被称为 Maven 仓库管理器(Repository Manager),主要有以下 3 种:
- Apache Archiva
- JFrog Artifactory
- Sonatype Nexus
我们使用:Sonatype Nexus
启动服务器(命令行)
nexus.exe /run nexus
访问服务器(默认端口:8081)
http://localhost:8081
修改基础配置信息
安装路径下etc目录中nexus-default.properties文件保存有nexus基础配置信息,例如默认访问端口修改服务器运行配置信息
安装路径下bin目录中nexus.vmoptions文件保存有nexus服务器启动对应配置信息,例如默认占用内存空间
私服仓库分类
仓库类别 | 英文名称 | 功能 | 关联操作 |
---|---|---|---|
宿主仓库 | hosted | 保存自主研发+第三方资源 | 上传 |
代理仓库 | proxy | 代理连接中央仓库 | 下载 |
仓库组 | group | 为仓库编组简化下载操作 | 下载 |
资源上传与下载
1.本地仓库访问私服
权限设置(setting.xml)
<!-- 配置访问私服的权限 --> <servers> <server> <id>maoge-release</id> <username>admin</username> <password>admin</password> </server> <server> <id>maoge-snapshot</id> <username>admin</username> <password>admin</password> </server> </servers>
地址设置(setting.xml)
<!--私服访问路径--> <mirror> <id>maven-public</id> <mirrorOf>*</mirrorOf> <url>http://localhost:8081/repository/maven-public/</url> </mirror>
2.工程上传到私服
在父工程的pom文件中编写:
<!--工程上传到私服设置-->
<distributionManagement>
<repository>
<id>maoge-release</id>
<url>http://localhost:8081/repository/maoge-release/</url>
</repository>
<snapshotRepository>
<id>maoge-snapshot</id>
<url>http://localhost:8081/repository/maoge-snapshot/</url>
</snapshotRepository>
</distributionManagement>
最后执行maven生命周期的deploy:
或使用命令行输入:
mvn deploy