拆分前项目地址:https://gitee.com/acgkaka/SpringBootExamples/tree/master/springboot-mybatis-plus
拆分后项目地址:https://gitee.com/acgkaka/SpringBootExamples/tree/master/springboot-mybatis-plus-modules
这里我们将一个典型的 spring mvc 项目的各个模块进行拆分,各模块之间通过接口进行通信。
(为了美观,我在图片上进行了顺序调整)
创建子模块的时候,可以在IDEA中直接右键项目文件夹,然后选择新建module:
新建模块
拷贝原始项目中对应的相关内容到modules_common模块中
将
<groupId>com.demogroupId>
<artifactId>modules_commonartifactId>
<version>1.0-SNAPSHOTversion>
执行 clean install
,确保模块可以独立安装,不会报编译错误
新建模块
拷贝原始项目中对应的相关内容到modules_pojo模块中
将
<groupId>com.demogroupId>
<artifactId>modules_pojoartifactId>
<version>1.0-SNAPSHOTversion>
执行 clean install
,确保模块可以独立安装,不会报编译错误
因为我的 User.java 中使用到了一些 MybatisPlus 的注解,所以需要在 modules_pojo 中就添加 MyBatisPlus 的依赖,下面是我的 User.java:
package com.demo.module.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import java.time.LocalDateTime;
import java.io.Serializable;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
/**
*
* 用户表
*
*
* @author ACGkaka
* @since 2021-04-25
*/
@Data
@EqualsAndHashCode(callSuper = false)
@NoArgsConstructor
@AllArgsConstructor
@TableName("t_user")
public class TUser implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键
*/
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
* 用户名
*/
private String username;
/**
* 密码
*/
private String password;
/**
* 创建时间
*/
private LocalDateTime createTime;
/**
* 更新时间
*/
private LocalDateTime updateTime;
}
新建模块
拷贝原始项目中对应的相关内容到modules_dao模块中
<groupId>com.demogroupId>
<artifactId>modules_daoartifactId>
<version>1.0-SNAPSHOTversion>
执行 clean install
,确保模块可以独立安装,不会报编译错误
新建模块
拷贝原始项目中对应的相关内容到modules_service模块中
将
<groupId>com.demogroupId>
<artifactId>modules_serviceartifactId>
<version>1.0-SNAPSHOTversion>
执行 clean install
,确保模块可以独立安装,不会报编译错误
新建模块
拷贝原始项目中对应的相关内容到modules_controller模块中
将
<groupId>com.demogroupId>
<artifactId>modules_controllerartifactId>
<version>1.0-SNAPSHOTversion>
由于modules_controller还使用了 spring-boot-starter-web,因此需要继承 spring-boot-starter-parent
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>2.4.5version>
<relativePath/>
parent>
启动modules_controller模块。
启动modules_controller模块后,我们可以看到日志中显示已经启动成功了:
浏览器调用服务接口,响应正常:
我们进行多模块拆分之后,如果我们中间有一个模块,例如 dao 模块,那么依赖 dao 模块的模块并不能知道 dao 模块是否有更新,因此我们需要一个单独的模块来统一管理所有的模块。
作用:聚合用于快速构建 maven 工程,一次性构建多个项目/模块。
制作方法:
创建一个空模块,打包类型定义为pom。
<packaging>pompackaging>
定义当前模块进行构建操作时关联的其他模块名称。
(如果在之前创建模块的时候,使用的是IDEA中右键->新建->模块的方式,会自动添加好相应的 module 配置)
<modules>
<module>modules_commonmodule>
<module>modules_pojomodule>
<module>modules_daomodule>
<module>modules_servicemodule>
<module>modules_controllermodule>
modules>
注意事项:参与聚合操作的模块最终执行顺序与模块间的依赖关系有关,与配置顺序无关。
我们在进行多模块拆分之后,如果不同模块之间使用的是相同依赖的不同版本,切不同版本之间不能相互兼容的话,就会导致依赖冲突。
这时候,我们可以使用一个模块来统一管理依赖的版本号,其他的模块只需指定依赖的部分坐标即可,不需要指定依赖的版本号了。
作用:通过继承可以实现在子工程中沿用父工程中的配置
制作方式:
在子工程中声明其父工程坐标与对应的位置
<parent>
<groupId>com.demogroupId>
<artifactId>springboot-mybatis-plus-modulesartifactId>
<version>1.0-SNAPSHOTversion>
<relativePath>../pom.xmlrelativePath>
parent>
既然子工程会沿用父工程中的依赖,这里我们就会想到之前拆分好的 modules_controller 模块中指定了父工程为 spring-boot-starter-parent包。
按住 Ctrl 点击 artifactId 可以进入到相应模块的 pom.xml 配置文件中。
我们可以看到 spring-boot-starter-parent 的 pom.xml 内容如下,其中并没有引用其他的依赖,而是又继承了 spring-boot-dependencies 工程。
我们进入 spring-boot-dependencies 的 pom.xml 中,内容如下,发现其中也并没有引用其他的依赖,而是有一个
标签:
可见父工程 spring-boot-starter-parent 主要是通过 spring-boot-dependencies 进行了一个依赖版本管理的功能,下面我们就可以删掉 spring-boot-starter-parent 父工程,自己指定 spring-boot-dependencies 进行配置管理即可。
在父工程中定义依赖管理(注意:这里只是声明版本,并不真实引入)
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-dependenciesartifactId>
<version>2.4.5version>
<type>pomtype>
<scope>importscope>
dependency>
dependencies>
dependencyManagement>
在子工程中定义依赖关系,无需声明依赖版本,版本参照父工程中依赖的版本。
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
<scope>testscope>
dependencies>
子工程可以从父工程中继承的资源如下:
看到这里,我们就可以把子模块的 groupId 和 version 去除掉了。
(一般情况下,子模块和父模块的组织ID和版本号保持一致,特殊情况也可以不一致)
我们在项目依赖过程中,经常会需要用到多个版本相同的依赖,例如:
如何更好地统一对这些版本进行管理呢?
作用
定义格式:
<properties>
<spring.version>5.1.9.RELEASEspring.version>
<junit.version>4.12junit.version>
properties>
调用格式:
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-contextartifactId>
<version>${spring.version}version>
dependency>
作用
调用格式:
${basedir}
${version}
${project.version}
作用
调用格式:
${settings.localRepository}
系统属性查询方式
mvn help:system
查询系统属性,可以看到有两个分区:System Properties 和 Environment Variables。
作用
调用格式:
${env.JAVA_HOME}
环境变量属性查询方式
mvn help:system
我们在进行项目管理的时候,除了需要对依赖的版本进行管理之外,还需要对配置文件进行管理。例如:jdbc.properties
作用
调用格式:
${jdbc.url}
开启配置文件加载pom属性
<resources>
<resource>
<directory>${project.basedir}/src/main/resourcesdirectory>
<filtering>truefiltering>
resource>
resources>
我们在开发过程中,经常会需要在不同环境进行部署,比如开发环境、测试环境、生产环境等,那么在不同环境下就需要进行不同的配置。能不能通过 Maven 来实现多个环境下不同配置的切换呢?
在多环境下,我们可以通过
<profiles>
<profile>
<id>pro_envid>
<properties>
<property>
<jdbc.url>jdbc:mysql://127.0.0.1:3306/ssm_dbjdbc.url>
property>
properties>
<activation>
<activeByDefault>trueactiveByDefault>
activation>
profile>
<profile>
<id>dev_envid>
......
profile>
profiles>
作用
调用格式
mvn 指令 -P 环境定义id
范例
mvn install -P pro_env
命令
# 方式一(推荐)
mvn 指令 -DskipTests
# 方式二
mvn 指令 -Dmaven.test.skip=true
<plugin>
<artifactId>maven-surefire-pluginartifactId>
<version>2.22.1version>
<configuration>
<skipTest>trueskipTest>
<includes>
<include>**/User*Test.javainclude>
includes>
<excludes>
<exclude>*/User*TestCase.javaexclude>
excludes>
configuration>
plugin>
打开下载地址,页面如下,我们选择 Windows 版本。
下载后文件如下:
解压后,文件内容如下:
使用 cmd 控制台命令行,进入 nexus-3.52.0-01\bin
目录,执行如下命令启动:
# .exe可以省略
nexus.exe /run nexus
启动过程有点长,启动成功后控制台内容如下所示:
访问地址为:http://localhost:8081
访问nexus地址,加载页面如下:
加载成功后,页面如下,我们点击右上角的登录:
第一次登录会提示你 admin
用户密码的存放位置:
打开文件所在目录:
打开 admin.password 文件:
输入密码,点击登录即可:
第一次登陆后需要进行相应的设置,点击 Next
:
修改密码后,点击 Next
:
配置是否允许匿名访问,选择 Disable
,点击 Next
:
完成初始配置,点击 Finish。
如果想修改端口,可以在 nexus-3.52.0-01\etc
目录下的 nexus-default.properties
文件中进行修改:
在这里修改端口,重启后即可生效:
打开 nexus-3.52.0-01\bin
目录中的 nexus.vmoptions
文件,可以对服务器的运行参数进行配置:(例如:-Xms指定最小运行内存,-Xmx指定最大运行内存)
在项目中,一部分我们自己创建的包会放到私服仓库上,一部分像Spring这类公共的包会放到中央仓库上。
这样就需要配置两个服务器地址,能不能合并一下呢?
当然可以,我们把私服扩展一下,在私服中单独存在一个仓库用来存放从中央仓库中获取资源,这样我们连接一个服务器地址即可。
为了区分我们自己资源的正式版本和临时版本,还需要存在一个单独用来存放临时版本的仓库。
为了更方便的获取依赖的位置,我们可以创建一个仓库组,方便对统一仓库组的其他仓库进行中的资源配置。
我们登录 Nexus 以后,可以看到页面上方有两个标签,左边是我们浏览资源用的,右边是设置 Nexus 服务器用的,默认是在左边。
在资源浏览页面的左边有四个标签,分别是:首页、搜索页面、浏览仓库、上传。我们对于仓库的浏览主要是在 Browse
页面中:
在 Browse 页面中,我们可以看到这里主要有三种图标,这三种图标就对应我们三种仓库:
点击页面上方切换到服务器设置界面, 点击 Repositories
-> Create repository
下拉,从 3 个 maven2
中选择 maven2 (hosted)
命名仓库,并选择对应的仓库类型,比如我创建一个用来存放发布版本的仓库叫:my-release
往下拉,选择 Create repository
,创建仓库。
我们可以看到仓库已经创建成功了。
为了后续方便操作,我们把刚刚创建好的仓库,添加到 maven-public
仓库组中,回头我们直接访问 maven-public
就都可以访问了,不用挨个去找了。
点击 maven-public
,往下拉可以看到右边是已经添加到群组中的仓库,我们把左边刚刚创建好的仓库移到右边,保存即可。
仓库创建好了,接下来我们就要往仓库中传一些资源。
点击页面上方的方框,回到仓库浏览界面 Browse
,点击我们刚才创建好的仓库。
点击 Upload component
进入上传界面。
将文件上传好,坐标信息填好后,就可以上传了。
注意:这里我创建的是 RELEASE 仓库,不要上传 SNAPSHOT 版本的 jar 包。
上传成功,点击 view it now
。
就可以看到我们上传的内容在仓库中的信息了。
或者在 Browse
页面中,点击我们的仓库查看:
如果想在仓库中删除依赖,直接选择某个依赖或者某个包进行删除即可:
(删除之后不会立刻消失,需要刷新页面)
Nexus 还在服务器设置页面,提供了用户/角色的操作,有兴趣的可以自己扩展了解下:
在页面上进行手工上传,主要是针对第三方的依赖进行操作,我们大部分情况下还是在 idea 中进行资源的上传与下载。
对于连接私服的地址、用户名和密码,我们在 maven 的 settings.xml 文件中进行配置:
配置本地仓库访问私服的权限(settings.xml)
<servers>
<server>
<id>my-releaseid>
<username>adminusername>
<password>adminpassword>
server>
<server>
<id>my-snapshotsid>
<username>adminusername>
<password>adminpassword>
server>
servers>
配置本地仓库资源来源(settings.xml)
<mirrors>
<mirror>
<id>nexus-aliyunid>
<mirrorOf>centralmirrorOf>
<url>http://maven.aliyun.com/nexus/content/groups/publicurl>
mirror>
<mirror>
<id>nexus-mineid>
<mirrorOf>*mirrorOf>
<url>http://localhost:8081/repository/maven-publicurl>
mirror>
mirrors>
当仓库组在查找资源时会从上往下逐一查找,所以我们直接配置 maven-public 即可。
怎么获取配置里面的 url 路径呢,我们可以去 Browse
页面,有一列叫 URL,我们点击这里的 copy
。
点击 Ctrl+C,就可以把路径拷贝下来了。
配置当前项目访问私服上传资源的保存位置(pom.xml)
<distributionManagement>
<repository>
<id>my-releaseid>
<url>http://localhost:8081/repository/my-release/url>
repository>
<snapshotRepository>
<id>my-snapshotsid>
<url>http://localhost:8081/repository/my-snapshots/url>
snapshotRepository>
distributionManagement>
发布资源到私服命令
mvn deploy
mvn deploy:deploy-file -Dfile=文件路径 -DgroupId=所属组ID -DartifactId=项目ID -Dversion=版本号 -Dpackaging=打包形式 -Durl=上传仓库路径 -DrepositoryId=仓库名称
示例:这里我将一个 kettle 的 jar 包上传到我刚创建好的 my-release
仓库中,命令如下:
(kettle-core-7.1.0.0-12.jar 与命令行在同一级目录)
mvn deploy:deploy-file -Dfile=kettle-core-7.1.0.0-12.jar -DgroupId=pentaho-kettle -DartifactId=kettle-core -Dversion=7.1.0.0-12 -Dpackaging=jar -Durl=http://localhost:8081/repository/my-release -DrepositoryId=my-release
执行结果:
mvn install:install-file -Dfile=文件路径 -DgroupId=所属组ID -DartifactId=项目名称 -Dversion=版本号 -Dpackaging=打包方式
示例:这里我将一个 kettle 的 jar 包上传到我的本地仓库中,命令如下:
mvn install:install-file -Dfile=kettle-core-7.1.0.0-12.jar -DgroupId=pentaho-kettle -DartifactId=kettle-core -Dversion=7.1.0.0-12 -Dpackaging=jar
执行结果:
整理完毕,完结撒花~