当前位置: 首页 > news >正文

Spring全家桶面试题, 只补充细节版本

Spring全家桶面试题, 补充细节版本(2021优化版)

@$Spring Boot的启动流程,分为以下两大部分:

SpringApplication的实例化

  • 推断应用类型是否是Web环境

  • 设置初始化器(Initializer)

  • 设置监听器(Listener)

  • 推断应用入口类(Main)

SpringApplication.run方法

  • 获取SpringApplicationRunListeners

  • 准备配置环境ConfigurableEnvironment

  • 创建ApplicationContext应用上下文

  • ApplicationContext前置处理

  • ApplicationContext刷新

  • ApplicationContext后置处理

完成了实例化,下面开始调用run方法

// 运行run方法
public ConfigurableApplicationContext run(String... args) {// 此类通常用于监控开发过程中的性能,而不是生产应用程序的一部分。StopWatch stopWatch = new StopWatch();stopWatch.start();ConfigurableApplicationContext context = null;Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();// 设置java.awt.headless系统属性,默认为true// Headless模式是系统的一种配置模式。在该模式下,系统缺少了显示设备、键盘或鼠标。configureHeadlessProperty();// KEY 1 - 获取SpringApplicationRunListenersSpringApplicationRunListeners listeners = getRunListeners(args);// 通知监听者,开始启动listeners.starting();try {ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);// KEY 2 - 根据SpringApplicationRunListeners以及参数来准备环境ConfigurableEnvironment environment = prepareEnvironment(listeners,applicationArguments);configureIgnoreBeanInfo(environment);// 准备Banner打印器 - 就是启动Spring Boot的时候打印在console上的ASCII艺术字体Banner printedBanner = printBanner(environment);// KEY 3 - 创建Spring上下文context = createApplicationContext();// 注册异常分析器analyzers = new FailureAnalyzers(context);// KEY 4 - Spring上下文前置处理prepareContext(context, environment, listeners, applicationArguments,printedBanner);// KEY 5 - Spring上下文刷新refreshContext(context);// KEY 6 - Spring上下文后置处理afterRefresh(context, applicationArguments);// 发出结束执行的事件listeners.finished(context, null);stopWatch.stop();if (this.logStartupInfo) {new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);}return context;}catch (Throwable ex) {handleRunFailure(context, listeners, exceptionReporters, ex);throw new IllegalStateException(ex);}
}

SpringBoot 自动装配

启动时扫描:SpringBoot 启动时,@EnableAutoConfiguration 触发对  `META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports` 的扫描,获取所有候选自动配置类。
条件过滤:通过条件注解(如 @Conditional)筛选出符合当前环境的自动配置类。
注册 Bean:自动配置类中的 @Bean 方法向容器注册组件,完成自动装配。

SpringBoot 的“自动装配”**不是黑魔法**,而是一条**“约定优于配置”的装配生产线**:  
`spring-boot-autoconfigure` 模块里预置了上百个`@Configuration`类,它们会**根据你引入的 jar、配置的参数以及运行环境**,**条件化地**把 Bean 注入容器。  
一句话:**“你加依赖,我配 Bean;你写参数,我改行为;什么都不要,我就按默认值跑。”**

下面按“面试可讲、源码可看、实战可用”三层展开。

------------------------------------------------
一、面试口语版(3 分钟能说清)
1. 启动入口  
`@SpringBootApplication` =  
`@EnableAutoConfiguration`(开自动装配)  
+ `@ComponentScan`(扫自己写的组件)  
+ `@SpringBootConfiguration`(声明配置类)。

2. 加载坐标  
`EnableAutoConfiguration` 导入 `AutoConfigurationImportSelector`,它从  
`META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports`  
读取 140+ 个自动配置类的全限定名(Spring Boot 2.7+ 废弃 `spring.factories`,3.x 彻底移除此文件)。

3. 条件判断  
每个自动配置类头上都挂着一堆 `@ConditionalOnXxx`:  
- `@ConditionalOnClass`  classpath 里有指定类才生效  
- `@ConditionalOnMissingBean`  容器里没这 Bean 才帮你配  
- `@ConditionalOnProperty`  配置项开关  
- ……(还有 10 来种)

   举例:`DataSourceAutoConfiguration` 只在  
classpath 下有 `javax.sql.DataSource` 且用户没自己配 `DataSource` Bean 时才启动。

4. 参数绑定  
生效后,配置类里用 `@EnableConfigurationProperties` 把  
`application.yml` 中的 `spring.datasource.*` 绑定到 `DataSourceProperties`,  
再调用 `DataSourceBuilder` 创建 `HikariDataSource` Bean 并注册。

5. 留给用户的“钩子”  
- 完全替代:自己写一个 `@Bean`,自动配置就退让(`@ConditionalOnMissingBean`)。  
- 微调参数:改 `application.yml` 即可。  
- 关闭某段:  
`spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration`

------------------------------------------------
二、源码速读路线(能点到文件名)
1. SpringApplication.run  
↓  
2. `refresh()` → `invokeBeanFactoryPostProcessors()`  
↓  
3. `ConfigurationClassPostProcessor` 解析 `@Configuration`  
↓  
4. `AutoConfigurationImportSelector.selectImports()`  
读取 `META-INF/spring/*.imports` 文件,得到 `List<String> candidateConfigurations`  
↓  
5. `ConditionEvaluator` 按 `@ConditionalOnXxx` 过滤,生成 `MatchResult`  
↓  
6. 剩余配置类被 `ConfigurationClassParser` 加载,其内部 `@Bean` 方法被 `Cglib` 增强后注册到 `DefaultListableBeanFactory`

------------------------------------------------
三、实战自定义 starter(10 行代码能跑通)
需求:项目里只要引入 `my-sms-spring-boot-starter`,就自动注入一个 `SmsTemplate`。

1. 新建模块 `my-sms-spring-boot-autoconfigure`
```java
@Configuration
@ConditionalOnClass(SmsTemplate.class)
@EnableConfigurationProperties(SmsProperties.class)
public class SmsAutoConfiguration {

    @Bean
@ConditionalOnMissingBean
public SmsTemplate smsTemplate(SmsProperties props) {
return new SmsTemplate(props.getAccessKey(), props.getSecret());
}
}
```

2. 新建 `META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports`
```
com.demo.sms.SmsAutoConfiguration
```

3. 再包一个 `my-sms-spring-boot-starter`(空 jar,只依赖上面 autoconfigure 模块 + 业务 SDK)

4. 业务方使用
```xml
<dependency>
<groupId>com.demo</groupId>
<artifactId>my-sms-spring-boot-starter</artifactId>
</dependency>
```
```yaml
sms.access-key=AKxxx
sms.secret=SECxxx
```
启动即得可注入的 `SmsTemplate`。

------------------------------------------------
四、常见坑 & 调优
1. 循环依赖报 `BeanCurrentlyInCreationException`  
→ 检查自动配置顺序,用 `@AutoConfigureAfter/@AutoConfigureBefore` 调整。

2. 启动慢  
→ 打开 `debug=true` 或 `spring.boot.autoconfigure.condition.OnClassCondition=TRACE` 看哪些条件未命中,排除无用配置。

3. 重复 Bean  
→ 用 `spring.autoconfigure.exclude` 或在自定义 starter 里加 `@ConditionalOnMissingBean`。

------------------------------------------------
一句话收拢  
自动装配 = **“在正确的时间,把正确的 Bean,按正确的配置,塞进容器”**;  
而 SpringBoot 把这套流程固化成了**条件注解 + 配置类 + META-INF 索引**,  
既让**用户零配置**,又留足**扩展/覆盖/排错**的口子,这才是它“开箱即用”的本质。

面试口诀(3 句背完)

1. 入口一注解:  
`@SpringBootApplication` 里藏 `@EnableAutoConfiguration`,开启自动装配。

2. 加载两步走:  
① 读文件:`META-INF/spring/*.imports` 拿出 140+ 自动配置类。  
② 做判断:`@ConditionalOnClass/@OnMissingBean` 等条件过滤,只留需要的。

3. 结果零配置:  
条件成立就帮你注册 Bean,参数用 `@ConfigurationProperties` 绑定到 yml;  
你写自己的 Bean 或改 yml,就能覆盖默认,实现“开箱即用”。

SPI 配置文件

SPI 配置文件变更SpringBoot 3 中,自动配置类的注册文件从 META-INF/spring.factories 迁移到了 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports(文本文件,每行一个自动配置类全类名)。原因:spring.factories 是 Spring 传统的 SPI 格式,而新格式更简洁,且避免了与其他 SPI 配置的冲突。示例(AutoConfiguration.imports):

com.example.config.MyAutoConfiguration
com.example.config.UserAutoConfiguration

http://www.dtcms.com/a/537490.html

相关文章:

  • 做网站可以挣钱吗微信公众平台网页版登录
  • 第2章-类加载子系统
  • 网站左侧悬浮导航芜湖学校网站建设电话
  • PyTorch2 Python深度学习 - 简介以及入门
  • 定制版网站建设费用湘潭网站建设湘潭振企专业
  • 自己做的小网站如何发布网络营销案例范文
  • 单体架构中的事件驱动架构:Java应用程序的渐进式重构
  • 成都网站开发的公司吉安县规划建设局网站
  • 有了域名怎么建设网站淘宝客网站是怎么做的
  • 铁岭做网站大学网页设计与制作教程
  • 工商工事上哪个网站做西安网站制作公司排名
  • 机关单位网站建设申请公司简介模板图片
  • 【Delphi】操纵EXE文件中的主图标(MAINICON)
  • 彭州建设网站陕西省建设执业资格注册中心网站
  • 济南企业上云网站建设如何让网站自适应手机
  • nginx基础入门篇-nginx部署-Yum
  • Leetcode每日一练--43
  • Nacos 配置中心:动态配置管理
  • cpp / c++零基础两周速成教学
  • 免费微场景制作网站深圳外贸公司有哪些公司
  • Selenium定位元素的方法css和xpath的区别
  • 什么网站可以自学ps做贵宾卡互联网营销师
  • 建站公司 深圳巴西网站后缀
  • LeetCode 3. 无重复字符的最长子串解析
  • 给你一个新的网站怎么做2017网站备案抽查
  • 杭州网站做的好公司公司品牌网络推广方案
  • PyTorch Geometric 图神经网络实战利器
  • 《深入浅出统计学》学习笔记(一)
  • 从登录场景看通用序列化协议:JSON 与 Protobuf 实践
  • 天津网站优化软件一个公司可以做两个网站吗