day17 SpringBoot原理与Maven高级-总结

实战总结:SpringBoot 原理 + Maven 高级

本文是对《14-1 后端Web进阶(SpringBoot原理)》和《14-2 后端Web进阶(Maven高级)》两份讲义的总结。
这一天是后端开发的最后一个篇章,偏向底层原理与工程化,目标:理解 SpringBoot 为什么”开箱即用”,掌握大型项目模块化管理。


上篇:SpringBoot 原理

一、配置优先级(5 种配置方式)

1. 三种配置文件优先级

SpringBoot 支持 propertiesymlyaml 三种格式,同时存在时优先级(从高到低):

1
2
3
1. application.properties   ← 最高
2. application.yml
3. application.yaml ← 最低

建议:项目内统一使用一种格式,yml 是主流。

2. 五种配置方式总览

除配置文件外,SpringBoot 还支持两种外部配置:

配置方式 格式 示例
命令行参数 --key=value --server.port=10010
Java 系统属性 -Dkey=value -Dserver.port=9000
properties 文件 key=value server.port=8081
yml 文件 缩进式 server:\n port: 8082
yaml 文件 缩进式 同 yml

3. 优先级排名(从高到低)

1
命令行参数 > Java系统属性 > properties > yml > yaml

4. 打包后指定参数

1
2
3
4
# 同时设置系统属性和命令行参数
java -Dserver.port=9000 -jar XXXXX.jar --server.port=10010

# 最终生效的是命令行参数 --server.port=10010

5. 注意事项

  • SpringBoot 打包需要 spring-boot-maven-plugin 插件(官网骨架自动添加)。
  • IDEA 中通过 Modify options → Add VM options / Program arguments 设置。

二、Bean 的管理

1. Bean 的作用域(@Scope)

作用域 说明 创建时机
singleton 单例(默认),容器内同名称 bean 只有一个 容器启动时
prototype 每次使用都创建新实例 第一次获取时
request 每个请求范围创建新实例(web 环境)
session 每个会话范围创建新实例(web 环境)
application 每个应用范围创建新实例(web 环境)

用法

1
2
3
@Scope("prototype") // 改为非单例
@RestController
public class DeptController { ... }

重点提醒

  • 默认 singleton 的 bean 在容器启动时创建,可用 @Lazy 延迟到第一次使用时创建。
  • 实际开发中绝大部分 bean 是单例,不需要配置 scope
  • prototype 的 bean 每次使用都会创建新实例。

2. 第三方 Bean 的管理(@Bean)

场景

第三方依赖中的类(如阿里云 OSS 工具类),无法在源码上加 @Component,需要用 @Bean 注解声明。

方式一:直接写在启动类(不推荐)

1
2
3
4
5
6
7
@SpringBootApplication
public class Application {
@Bean
public AliyunOSSOperator aliyunOSSOperator(AliyunOSSProperties props) {
return new AliyunOSSOperator(props);
}
}

方式二:配置类(推荐)

1
2
3
4
5
6
7
@Configuration
public class OSSConfig {
@Bean
public AliyunOSSOperator aliyunOSSOperator(AliyunOSSProperties props) {
return new AliyunOSSOperator(props);
}
}

注意事项

  • @Bean 默认 bean 名称 = 方法名,可用 name/value 属性自定义。
  • 第三方 bean 需要依赖其他 bean 时,直接在方法形参中声明,Spring 自动按类型装配。

三、SpringBoot 原理剖析

1. SpringBoot 的两大核心

功能 解决的问题 原理
起步依赖 依赖配置繁琐 Maven 依赖传递
自动配置 bean 声明和配置繁琐 @Import + 配置文件 + @Conditional

2. 起步依赖原理

1
2
3
4
5
引入 spring-boot-starter-web

Maven 依赖传递特性

自动引入 json、web、webmvc、tomcat 等所有 web 开发常见依赖

本质就是 Maven 的依赖传递,把 web 开发所需的常见依赖都预先集成好。

3. 自动配置原理(核心!)

① 问题引入

引入第三方依赖后,第三方包中的 @Component不会被扫描到,因为 @SpringBootApplication 只扫描启动类所在包及子包。

1
2
启动类包:com.itheima   ← 能扫描
第三方包:com.example ← 扫描不到

② 四种解决方案对比

方案 写法 缺点
@ComponentScan @ComponentScan({"com.itheima","com.example"}) 繁琐、性能低
@Import 普通类 @Import(TokenParser.class) 需要知道类名
@Import 配置类 @Import(HeaderConfig.class) 需要知道配置类
@Import ImportSelector @Import(MyImportSelector.class) 需要写实现类
@EnableXxxxx(最优) 第三方提供,封装了 @Import

SpringBoot 采用的是 方案④/⑤ 的思路。

③ 源码跟踪:@SpringBootApplication

1
2
3
4
5
6
7
8
9
10
@SpringBootApplication
├── @SpringBootConfiguration → 声明启动类是配置类
├── @ComponentScan → 包扫描(启动类所在包及子包)
└── @EnableAutoConfiguration → 自动配置核心!
└── @Import(AutoConfigurationImportSelector.class)
└── selectImports()
└── getAutoConfigurationEntry()
└── getCandidateConfigurations()
└── 读取 META-INF/spring/
org.springframework.boot.autoconfigure.AutoConfiguration.imports

④ 自动配置执行流程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
SpringBoot 启动

@SpringBootApplication 中的 @EnableAutoConfiguration

@Import 导入 AutoConfigurationImportSelector

selectImports() 方法读取所有依赖 jar 包中的
META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 文件

获取文件中定义的所有自动配置类的全限定名

通过 @Import 将这些配置类加载到 IOC 容器

配置类中 @Bean 标识的方法被调用,返回值注册为 bean

@Conditional 条件装配:满足条件才真正注册

⑤ 关键文件位置

1
2
任意 SpringBoot 起步依赖 jar 包内:
META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports

文件内容示例(每行一个配置类全限定名):

1
2
3
org.springframework.boot.autoconfigure.gson.GsonAutoConfiguration
org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration
...

4. @Conditional 条件装配

自动配置类中声明 bean 时,常加 @Conditional 系列注解,满足条件才注册

注解 判断条件
@ConditionalOnClass 环境中存在指定字节码文件时才注册
@ConditionalOnMissingBean 环境中不存在指定类型/名称的 bean 时才注册
@ConditionalOnProperty 配置文件中存在指定属性和值时才注册

代码示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@Configuration
public class HeaderConfig {

@Bean
@ConditionalOnClass(name = "io.jsonwebtoken.Jwts")
// 项目中存在 Jwts 类时才注册
public HeaderParser headerParser() {
return new HeaderParser();
}

@Bean
@ConditionalOnMissingBean
// 容器中没有 HeaderParser 类型的 bean 时才注册
public HeaderParser headerParser2() {
return new HeaderParser();
}

@Bean
@ConditionalOnProperty(name = "name", havingValue = "itheima")
// application.yml 中有 name: itheima 时才注册
public HeaderParser headerParser3() {
return new HeaderParser();
}
}

这就是为什么 imports 文件中定义了上百个配置类,但并不是所有 bean 都会被注册——只有条件满足的才会真正生效。

5. 自动配置原理总结图

1
2
3
4
5
6
7
8
9
10
11
┌─────────────────────────────────────────────────────────────┐
│ @SpringBootApplication │
│ ├─ @SpringBootConfiguration (启动类=配置类) │
│ ├─ @ComponentScan (扫描启动类包及子包) │
│ └─ @EnableAutoConfiguration ★自动配置核心 │
│ └─ @Import(AutoConfigurationImportSelector) │
│ └─ 读取 imports 文件 │
│ └─ 加载所有自动配置类 │
│ └─ @Conditional 条件装配 │
│ └─ 满足条件 → 注册到 IOC 容器 │
└─────────────────────────────────────────────────────────────┘

四、自定义 Starter

1. 为什么需要自定义 Starter

第三方技术(如阿里云 OSS)官方未提供 starter 时,每个项目都要重复配置:引入依赖 + 写配置类 + 写工具类。封装成 starter 后,引入一个依赖即可使用

2. 命名规范

来源 命名规则 示例
SpringBoot 官方 spring-boot-starter-xxxx spring-boot-starter-web
第三方组织 xxxx-spring-boot-starter aliyun-oss-spring-boot-starter

3. 模块结构(两个模块)

1
2
3
4
5
6
7
8
9
10
aliyun-oss-spring-boot-starter          (依赖管理)
└── 依赖 aliyun-oss-spring-boot-autoconfigure

aliyun-oss-spring-boot-autoconfigure (自动配置)
├── AliyunOSSAutoConfiguration (自动配置类)
├── AliyunOSSProperties (配置属性类)
├── AliyunOSSOperator (工具类)
└── resources/META-INF/spring/
└── org.springframework.boot.autoconfigure.AutoConfiguration.imports
└── 内容:com.aliyun.oss.AliyunOSSAutoConfiguration

4. 实现步骤

① 创建 starter 模块(仅 pom.xml)

1
2
3
4
5
6
7
8
9
10
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-oss-spring-boot-starter</artifactId>

<dependencies>
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-oss-spring-boot-autoconfigure</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>

② 创建 autoconfigure 模块

配置属性类(去掉 @Component):

1
2
3
4
5
6
@Data
@ConfigurationProperties(prefix = "aliyun.oss")
public class AliyunOSSProperties {
private String endpoint;
private String bucketName;
}

工具类(去掉 @Component@Autowired,改为构造器注入):

1
2
3
4
5
6
7
8
public class AliyunOSSOperator {
private final AliyunOSSProperties aliyunOSSProperties;

public AliyunOSSOperator(AliyunOSSProperties aliyunOSSProperties) {
this.aliyunOSSProperties = aliyunOSSProperties;
}
// ... 业务方法
}

自动配置类(核心):

1
2
3
4
5
6
7
8
9
@Configuration
@EnableConfigurationProperties(AliyunOSSProperties.class)
public class AliyunOSSAutoConfiguration {

@Bean
public AliyunOSSOperator aliyunOSSOperator(AliyunOSSProperties props) {
return new AliyunOSSOperator(props);
}
}

③ 创建 imports 配置文件

文件路径:src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports

文件内容:

1
com.aliyun.oss.AliyunOSSAutoConfiguration

5. 使用方式

1
2
3
4
5
6
<!-- 引入起步依赖 -->
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-oss-spring-boot-starter</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
1
2
3
4
5
# application.yml 配置属性
aliyun:
oss:
endpoint: https://oss-cn-beijing.aliyuncs.com
bucketName: java422-web-ai
1
2
3
// 直接注入使用
@Autowired
private AliyunOSSOperator aliyunOSSOperator;

下篇:Maven 高级

五、分模块设计与开发

1. 为什么分模块

不分模块的问题

  • 项目庞大,难以管理和维护
  • 通用组件难以复用(业务代码混在一起,依赖会引入全部代码)

分模块的好处

  • 方便项目管理维护、扩展
  • 方便模块间相互调用、资源共享

2. 拆分策略

策略 示例
按功能模块拆分 公共组件、商品模块、搜索模块、订单模块
按层拆分 公共组件、实体类、控制层、业务层、数据访问层
功能 + 层混合 综合以上两种

3. 案例:tlias 项目拆分

1
2
3
tlias-web-management   (主业务模块,依赖 pojo 和 utils)
├── tlias-pojo (实体类:Result、PageBean、Emp、Dept...)
└── tlias-utils (工具类:JwtUtils、AliyunOSSOperator...)

拆分步骤(以 pojo 为例):

  1. 创建 Maven 模块 tlias-pojo
  2. 创建包 com.itheima.pojo(与原项目包名一致)
  3. 复制实体类到新模块
  4. 在新模块 pom.xml 中引入所需依赖(lombok、spring-boot-starter)
  5. 删除原项目的 pojo 包
  6. 在原项目 pom.xml 中引入 tlias-pojo 坐标

注意:实际开发是先设计模块再编码,不会先开发完再拆分。


六、继承与聚合

1. 继承

① 作用

简化依赖配置、统一管理依赖。子工程继承父工程后,自动继承父工程的依赖。

② 多重继承(SpringBoot 项目特殊处理)

由于 Maven 不支持多继承,而 SpringBoot 项目必须继承 spring-boot-starter-parent,所以采用多重继承

1
2
3
4
5
spring-boot-starter-parent
↑ 继承
tlias-parent (自定义父工程)
↑ 继承
tlias-pojo / tlias-utils / tlias-web-management

③ 父工程配置

1
2
3
4
5
6
7
8
9
10
11
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.8</version>
<relativePath/>
</parent>

<groupId>com.itheima</groupId>
<artifactId>tlias-parent</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging> <!-- 父工程必须是 pom -->

④ 子工程配置

1
2
3
4
5
6
7
8
9
<parent>
<groupId>com.itheima</groupId>
<artifactId>tlias-parent</artifactId>
<version>1.0-SNAPSHOT</version>
<relativePath>../tlias-parent/pom.xml</relativePath>
</parent>

<artifactId>tlias-utils</artifactId>
<!-- groupId 可省略,自动继承父工程 -->

2. 版本锁定(dependencyManagement)

① 场景

部分依赖不是所有模块都用到(如 jwt 只有 web 模块用),不能直接放父工程的 <dependencies>。但又要保证多模块使用同一依赖时版本一致。

② 父工程配置

1
2
3
4
5
6
7
8
9
10
<!-- 只锁定版本,不会真正引入 -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
</dependencies>
</dependencyManagement>

③ 子工程配置

1
2
3
4
5
6
7
<dependencies>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<!-- 不需要写 version,由父工程统一管理 -->
</dependency>
</dependencies>

④ 面试题:<dependencies> vs <dependencyManagement>

对比项 <dependencies> <dependencyManagement>
作用 直接依赖 统一管理版本
子工程是否自动继承 是(直接引入) 否(需要自己引入,但无需版本号)
父工程是否引入该依赖

3. 属性配置(properties)

集中管理版本号,修改时只需改一处:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<properties>
<lombok.version>1.18.34</lombok.version>
<jwt.version>0.9.1</jwt.version>
<aliyun.oss.version>3.17.4</aliyun.oss.version>
</properties>

<dependencyManagement>
<dependencies>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>${jwt.version}</version> <!-- 引用属性 -->
</dependency>
</dependencies>
</dependencyManagement>

这就是为什么 SpringBoot 项目中很多依赖都不需要写 <version>——父工程 spring-boot-starter-parent 已经用 dependencyManagement 统一管理了。

4. 聚合

① 作用

将多个模块组织成一个整体,一键构建(清理、编译、测试、打包、安装),无需按依赖关系手动一个个构建。

② 配置

在聚合工程(通常是父工程)的 pom.xml 中:

1
2
3
4
5
<modules>
<module>../tlias-pojo</module>
<module>../tlias-utils</module>
<module>../tlias-web-management</module>
</modules>

③ 效果

tlias-parent 上执行 package,所有聚合的子模块都会自动执行 package。

5. 继承与聚合对比

对比项 继承 聚合
作用 简化依赖配置、统一管理依赖 快速构建项目
配置位置 子工程配置 <parent> 聚合工程配置 <modules>
感知关系 父工程无法感知哪些子模块继承了自己 聚合工程能感知参与聚合的模块
打包方式 都是 pom 都是 pom
共同点 都是设计型模块,无实际业务内容 同左

实际开发中,父工程通常同时是聚合工程,两种关系制作在同一个 pom.xml 中。

6. Maven 三种打包方式

打包方式 用途
jar 普通模块(默认),SpringBoot 项目基本是 jar(内嵌 tomcat)
war 需部署到外部 tomcat 的 web 程序
pom 父工程或聚合工程,不写代码,仅做依赖管理

七、私服

1. 私服是什么

  • 架设在公司局域网内部的仓库服务,是一种特殊的远程仓库。
  • 用来代理位于外部的中央仓库,解决团队内部资源共享问题。
  • 一个公司/项目只需一台私服(无需自己搭建,会使用即可)。

2. 依赖查找顺序

1
2
3
1. 本地仓库     (没有就找私服)
2. 私服仓库 (没有就找中央仓库)
3. 中央仓库 (下载后存到私服和本地仓库)

3. 私服仓库类型

仓库 存储内容
RELEASE 自己开发的发布版本(稳定)
SNAPSHOT 自己开发的快照版本(开发中)
Central 从中央仓库下载的第三方依赖

4. 项目版本说明

版本类型 特点
RELEASE(发布版本) 功能稳定、可发行,存入 RELEASE 仓库
SNAPSHOT(快照版本) 功能不稳定、开发中,存入 SNAPSHOT 仓库

5. 资源上传与下载(三步配置 + 一条指令)

① 配置私服访问用户名/密码(settings.xml 的 servers)

1
2
3
4
5
6
7
8
9
10
<server>
<id>maven-releases</id>
<username>admin</username>
<password>admin</password>
</server>
<server>
<id>maven-snapshots</id>
<username>admin</username>
<password>admin</password>
</server>

② 配置私服下载地址(settings.xml 的 mirrors)

1
2
3
4
5
<mirror>
<id>maven-public</id>
<mirrorOf>*</mirrorOf>
<url>http://localhost:8081/repository/maven-public/</url>
</mirror>

③ 配置项目上传地址(项目 pom.xml 的 distributionManagement)

1
2
3
4
5
6
7
8
9
10
11
12
<distributionManagement>
<!-- release 版本上传地址 -->
<repository>
<id>maven-releases</id>
<url>http://localhost:8081/repository/maven-releases/</url>
</repository>
<!-- snapshot 版本上传地址 -->
<snapshotRepository>
<id>maven-snapshots</id>
<url>http://localhost:8081/repository/maven-snapshots/</url>
</snapshotRepository>
</distributionManagement>

④ 执行 deploy 指令

1
mvn deploy

在聚合工程(tlias-parent)上执行 deploy,所有子模块都会上传到私服。

6. 完整流程图

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
┌─── A 团队开发 tlias-utils ───┐
│ 1. mvn deploy │
│ 2. 上传到私服 SNAPSHOT 仓库 │
└──────────────────────────────┘

┌─── 私服(局域网内) ─────────┐
│ maven-snapshots 仓库 │
│ 存有 tlias-utils-x.x.jar │
└──────────────────────────────┘

┌─── B 团队使用 tlias-utils ───┐
│ 1. pom.xml 引入坐标 │
│ 2. 本地仓库没有 → 私服下载 │
│ 3. 直接使用工具类 │
└──────────────────────────────┘

速查篇:高频考点与易错点

一、SpringBoot 原理速查

1. 配置优先级口诀

1
2
命令行参数 > 系统属性 > properties > yml > yaml
-- -D 文件 文件 文件

2. @SpringBootApplication 三大注解

1
2
3
4
5
@SpringBootApplication
├─ @SpringBootConfiguration → 启动类是配置类
├─ @ComponentScan → 包扫描(启动类包及子包)
└─ @EnableAutoConfiguration → 自动配置核心
└─ @Import(AutoConfigurationImportSelector)

3. 自动配置关键文件

1
META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports

4. @Conditional 三兄弟

注解 判断什么
@ConditionalOnClass 类路径有没有这个类
@ConditionalOnMissingBean 容器里有没有这个 bean
@ConditionalOnProperty 配置文件有没有这个属性值

二、Maven 高级速查

1. 父工程必要配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<packaging>pom</packaging>

<!-- 聚合 -->
<modules>
<module>子模块相对路径</module>
</modules>

<!-- 版本锁定 -->
<dependencyManagement>
<dependencies>...</dependencies>
</dependencyManagement>

<!-- 属性 -->
<properties>
<xxx.version>x.x.x</xxx.version>
</properties>

<!-- 上传私服 -->
<distributionManagement>
<repository>...</repository>
<snapshotRepository>...</snapshotRepository>
</distributionManagement>

2. settings.xml 三处配置

1
2
3
<servers>      <!-- 私服账号密码 -->
<mirrors> <!-- 私服下载镜像 -->
<profiles> <!-- 仓库地址配置 -->

3. Maven 生命周期对应操作

指令 作用
clean 清理 target
compile 编译
test 测试
package 打包
install 安装到本地仓库
deploy 上传到私服

三、易错点提醒

  1. 配置优先级不是固定的:5 种方式同时存在时,按 命令行 > 系统属性 > properties > yml > yaml 生效。

  2. prototype bean 不会在启动时创建:而是在第一次 getBean() 时创建,每次都新建。

  3. @Bean 方法形参就是依赖注入:第三方 bean 需要其他 bean 时,直接在方法参数中声明,Spring 自动装配。

  4. @ComponentScan 扫描范围有限:只扫启动类所在包及子包,第三方包扫不到,所以才需要 @Import 机制。

  5. imports 文件路径要准确:必须是 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports,路径错一点都不会加载。

  6. @ConditionalOnMissingBean 的妙用:自定义配置覆盖默认配置就是靠它——当用户自己定义了 bean,SpringBoot 默认的就不注册。

  7. 自定义 starter 必须两个模块:starter(依赖管理)+ autoconfigure(自动配置),缺一不可。

  8. autoconfigure 模块中不能再用 @Component:因为包扫描扫不到,必须用 @Configuration + @Bean + imports 文件。

  9. 父工程 packaging 必须是 pom:否则无法被子工程继承。

  10. dependencyManagement 不会真正引入依赖:子工程还需要自己在 <dependencies> 中声明,只是不需要写 version。

  11. relativePath:子工程配置父工程时,<relativePath>../tlias-parent/pom.xml</relativePath> 指定父 pom 相对位置;不指定则从本地/远程仓库查找。

  12. 聚合工程能感知子模块,继承不能感知:聚合是父知道子,继承是子知道父。

  13. deploy 前 settings.xml 必须配好 servers 的 id:id 要和 pom.xml 中 distributionManagement 的 repository id 一致(如 maven-releases)。

  14. SNAPSHOT vs RELEASE:版本号带 -SNAPSHOT 上传到 snapshots 仓库,不带则上传到 releases 仓库。


一图回顾全天知识

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
┌─────────────────── SpringBoot 原理 ───────────────────┐
│ │
│ 配置优先级 (5种) │
│ 命令行 > 系统属性 > properties > yml > yaml │
│ │
│ Bean 管理 │
│ ├─ 作用域: singleton(默认) / prototype / ... │
│ └─ 第三方Bean: @Bean + @Configuration │
│ │
│ 自动配置原理 │
│ @SpringBootApplication │
│ └─ @EnableAutoConfiguration │
│ └─ @Import(AutoConfigurationImportSelector) │
│ └─ 读取 imports 文件 │
│ └─ @Conditional 条件装配 │
│ │
│ 自定义 Starter │
│ ├─ starter 模块 (依赖管理) │
│ └─ autoconfigure 模块 │
│ ├─ @Configuration + @Bean │
│ └─ imports 文件 │
└───────────────────────────────────────────────────────┘

┌─────────────────── Maven 高级 ────────────────────────┐
│ │
│ 分模块设计 │
│ 按功能 / 按层 / 混合 │
│ │
│ 继承 (简化配置) │
│ ├─ 父工程 packaging=pom │
│ ├─ dependencyManagement (锁版本不引入) │
│ └─ properties (集中管理版本号) │
│ │
│ 聚合 (一键构建) │
│ └─ <modules> 子模块列表 │
│ │
│ 私服 (团队共享) │
│ ├─ settings.xml: servers/mirrors/profiles │
│ ├─ pom.xml: distributionManagement │
│ └─ mvn deploy │
└───────────────────────────────────────────────────────┘

附:复习自测清单

SpringBoot 原理

  • 能说出 5 种配置方式及其优先级
  • 能说出 Bean 的 5 种作用域及默认值
  • 能用 @Bean + @Configuration 管理第三方 bean
  • 能画出 @SpringBootApplication 的三大注解及其作用
  • 能说出自动配置的完整流程(imports 文件 → @Import → @Conditional)
  • 能说出三种 @Conditional 子注解的作用
  • 能独立实现一个自定义 starter

Maven 高级

  • 能说出分模块设计的两种策略
  • 能配置父工程继承关系(多重继承)
  • 能区分 <dependencies><dependencyManagement>
  • 能用 properties 集中管理版本号
  • 能配置聚合关系并一键构建
  • 能说出继承与聚合的相同点和不同点
  • 能配置私服的三步配置并执行 deploy
  • 能区分 RELEASE 和 SNAPSHOT 版本