1. 前言
1.1 maven官网
1.2 本文需要解释清楚的知识点
- maven的聚合和继承是两个不同的特性(官网的说法),看懂spring cloud项目需要同时掌握
- 聚合和继承的概念与设计模式中的基本概念一脉相承,以下用java类比
- 弄清楚
<dependencyManagement>中的 <dependencies>
和普通 <dependencies>
的区别 - 弄清楚使用方法后,拓展
<pluginManagement>
的用法
1.3 需要的前置知识
- 了解maven 的独立安装及配置
- 了解maven 生命周期
- 了解maven 的spring boot插件
spring-boot-maven-plugin
的命令行方式打包
1.4 文中的词典
开发者的spring cloud项目
– 微服务的项目开发者的spring boot项目
– 微服务架构中的子微服务开发者顶级的spring boot项目
– 微服务架构中有着统一配置作用的微服务spring boot框架
– spring团队开发的框架
2. 继承
单继承,由子类控制,group id
默认继承至父项目
group id
通常是指一个大项目的域名或唯一标识,一个spring cloud
项目只有一个group id
artifact id
具有实义的模块名,形如:spring-boot-starter-parent
spring boot框架的group id :org.springframework.boot
spring boot项目的group id : 项目开发者自定义,但是要统一
spring cloud项目的group id : 所有spring boot统一化配置的group id
当我们在选择spring cloud版本时,常常就是用一个spring boot项目作为版本管理的项目,即:
spring boot 2.5.x
||
微服务项目中顶级项目cloud
继承 spring boot 2.5.x
,并约定spring cloud
版本
||
微服务的其他版本继承cloud项目
, 并在约定好spring cloud
版本中选择套件
2.1 顶级父类pom配置
<artifactId>parent</artifactId>
<groupId>com.james</groupId>
<version>0.0.1-SNAPSHOT</version>
2.2 单继承下的子类pom 配置
<parent>
<artifactId>father</artifactId>
<groupId>com.james</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>parent-eureka-server</artifactId>
顶级父类不需要写<parent>
, 子类都需要写。接下来探究spring boot
框架下的顶级父类
- 类比 java
public class Parent { void dependencies(){} }
public class Son extends Parent{ }
2.3 spring boot 运用的继承关系
开发者的spring cloud项目
由 开发者的spring boot项目
组成的,则开发者顶级的spring boot项目
也是一个spring boot项目。
所以pom结构:开发者顶级的spring boot项目
继承 spring-boot-starter-parent
<!-- Spring Boot项目都继承spring-boot-starter-parent的起步依赖-->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.8</version>
</parent>
<groupId>com.james</groupId>
<artifactId>cloud</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>cloud</name>
- 看继承关系中得到的依赖, 向上找父项目
spring-boot-dependencies
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.5.8</version>
</parent>
<artifactId>spring-boot-starter-parent</artifactId>
<packaging>pom</packaging>
<name>spring-boot-starter-parent</name>
<description>Parent pom providing dependency and plugin management for applications built with Maven</description>
- 确定
spring boot框架
最顶级的依赖是spring-boot-dependencies
spring-boot-dependencies
使用<dependencyManagement>
和<properties>
规定了子类所有的默认依赖
<dependencyManagement>
<dependencies>
<dependency>
</dependency>
</dependencies>
</dependencyManagement>
- 区别于直接写
<dependencies>
,<dependencyManagement>
仅仅是子类的依赖版本声明,不会去中央仓库下载jar
包。 - 子类可以自由选择是否继承,默认是自动继承的。即普通的
<dependencies>
若存在父类相同的依赖,不指定版本号的情况会继承父类声明的版本号,从中央仓库下载jar
包并导入classpath,所有子类也自动依赖父类下载的jar
包并导入classpath。
2.4 项目中使用继承引入spring cloud版本管理
- spring
开发者的spring boot项目
用<dependencyManagement>
声明了开发者的spring cloud项目
的依赖,总的来说,就是使用maven继承关系管理了项目的依赖(spring cloud)。
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
PS: <type>pom<type> <scope>import</scop>
说明spring-cloud-dependencies
的<pacaking>为pom
, 是一个依赖的描述文件,里面有所有spring cloud组件
的版本定义,官方打包成一个pom
文件,开发者只用引入该文件等价于映入了所有spring cloud组件
组件默认版本,使得开发者的pom更加简洁。
3. 聚合
3.1 顶级父类pom配置
<!-- 用于聚合子项目的顶级工程, 打包方式为设置为pom -->
<packaging>pom</packaging>
<!-- 被聚合的模块, value为被聚合模块的 artifactId -->
<modules>
<module>cloud-order</module>
<module>cloud-eureka-server</module>
<module>cloud-supplier</module>
</modules>
- 类比 Java
public class Parent {
Son son;
Girl girl;
}
3.2 spring cloud 使用聚合实现被聚合项目的统一打包
在顶级项目目录执行
mvn package spring-boot:repackage
就可以在子项目cloud-eureka-server
中执行。说明顶级项目聚合的子项目会跟着顶级项目一起打包
java -jar cloud-eureka-server\target\cloud-eureka-server-0.0.1-SNAPSHOT.jar
4. 后记
maven的继承:建立起子类找父类的联系
maven的聚合:建立起父类找子类的联系
所以,spring cloud 中的所有spring boot项目都被整合起来了。
另外,maven的许多实验需要用命令行验证,idea的启动夹杂了很多私货不利于研究maven原理。这里贴以下idea 启动的命令行
java.exe
-Dmaven.multiModuleProjectDirectory=D:\cloud
-Dmaven.home=D:\maven3.8
-Dclassworlds.conf=D:\maven3.8\bin\m2.conf
-Dmaven.ext.class.path=D:\idea\plugins\maven\lib\maven-event-listener.jar
-javaagent:D:\idea\lib\idea_rt.jar=12953:D:\idea\bin
-Dfile.encoding=UTF-8
-classpath D:\maven3.8\boot\plexus-classworlds-2.6.0.jar;D:\maven3.8\boot\plexus-classworlds.license org.codehaus.classworlds.Launcher
-Didea.version=2020.3.2 -s D:\maven3.8\conf\settings.xml
-Dmaven.repo.local=D:\maven3.8\local_repository package
4.1 普通<dependencies>
的应用。
如果微服务架构中的子微服务都是web应用,可以在开发者顶级的spring boot项目
中定义。则所有微服务都可以省略写这个依赖。
- 顶级的spring boot项目pom:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
子类的spring boot项目
pom:
不用写,自动继承
4.2 <dependencyManagement>中的 <dependencies>
的应用
顶级的spring boot项目
pom:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
子类的spring boot项目
pom:
写spring cloud 组件不需要制定版本号
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
4.3 相同原理的衍生 <build>
指定所有项目单独打包使用spring boot插件。同样的,需要隔离的话用<pluginManagement>
包住即可。
顶级的spring boot项目
pom:
<build>
<plugins>
<!--spring boot的jar包跟传统的web项目不同,需要插件支持maven打出能直接运行的jar包-->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>