0

0

《面试八股文》之 Spring 18卷

Java后端技术全栈

Java后端技术全栈

发布时间:2023-08-22 15:55:59

|

1129人浏览过

|

来源于Java后端技术全栈

转载

「《面试八股文》之 spring 18卷」 又新鲜出炉了,这次整理了一下关于 spring 的面试题,网上也翻了翻关于 spring 的面试题,汇总了一下,基本都在这里了,当然可能有些过于基本的概念我是直接整理到某一问当中了,就没有单独再开设一问,祝大家面试顺利~



  • 1.spring 中都用到了哪些设计模式?

  • 2.spring 中有哪些核心模块?

  • 3.说一下你理解的 IOC 是什么?

  • 4.spring 中的 IOC 容器有哪些?有什么区别?

  • 5.那 BeanFactory 和 FactoryBean 又有什么区别?

  • 6.@Repository、@Service、@Compent、@Controller它们有什么区别?

  • 7.那么 DI 又是什么?

  • 8.说说 AOP 是什么?

  • 9.动态代理和静态代理有什么区别?

  • 10.JDK 动态代理和 CGLIB 代理有什么区别?

    Stable Diffusion 2.1 Demo
    Stable Diffusion 2.1 Demo

    最新体验版 Stable Diffusion 2.1

    下载
  • 11.Spring AOP 和 AspectJ AOP 有什么区别?

  • 12.spring 中 Bean 的生命周期是怎样的?

  • 13.spring 是怎么解决循环依赖的?

  • 14.为什么要使用三级缓存,二级缓存不能解决吗?

  • 15.@Autowired 和 @Resource 有什么区别?

  • 16.spring 事务隔离级别有哪些?

  • 17.spring 事务的传播机制有哪些?

  • 18.springBoot 自动装配原理?



1.spring 中都用到了哪些设计模式?

《面试八股文》之 Spring 18卷
  • 「1.工厂设计模式」: 比如通过 BeanFactory 和 ApplicationContext 来生产 Bean 对象
  • 「2.代理设计模式」:  AOP 的实现方式就是通过代理来实现,Spring主要是使用 JDK 动态代理和 CGLIB 代理
  • 「3.单例设计模式」: Spring 中的 Bean 默认都是单例的
  • 「4.模板方法模式」: Spring 中 jdbcTemplate 等以 Template 结尾的对数据库操作的类,都会使用到模板方法设计模式,一些通用的功能
  • 「5.包装器设计模式」: 我们的项目需要连接多个数据库,而且不同的客户在每次访问中根据需要会去访问不同的数据库。这种模式让我们可以根据客户的需求能够动态切换不同的数据源
  • 「6.观察者模式」: Spring 事件驱动模型观察者模式的
  • 「7.适配器模式」:Spring AOP 的增强或通知(Advice)使用到了适配器模式

2.spring 中有哪些核心模块?

《面试八股文》之 Spring 18卷
  • 1.「Spring Core」:Spring核心,它是框架最基础的部分,提供IOC和依赖注入DI特性
  • 2.「Spring Context」:Spring上下文容器,它是 BeanFactory 功能加强的一个子接口
  • 3.「Spring Web」:它提供Web应用开发的支持
  • 4.「Spring MVC」:它针对Web应用中MVC思想的实现
  • 5.「Spring DAO」:提供对JDBC抽象层,简化了JDBC编码,同时,编码更具有健壮性
  • 6.「Spring ORM」:它支持用于流行的ORM框架的整合,比如:Spring + Hibernate、Spring + iBatis、Spring + JDO的整合等
  • 7.「Spring AOP」:即面向切面编程,它提供了与AOP联盟兼容的编程实现

3.说一下你理解的 IOC 是什么?

《面试八股文》之 Spring 18卷

首先 IOC 是一个「容器」,是用来装载对象的,它的核心思想就是「控制反转」

那么究竟「什么是控制反转」?

控制反转就是说,「把对象的控制权交给了 spring,由 spring 容器进行管理」,我们不进行任何操作

那么为「什么需要控制反转」?

我们想象一下,没有控制反转的时候,我们需要「自己去创建对象,配置对象」,还要「人工去处理对象与对象之间的各种复杂的依赖关系」,当一个工程的量起来之后,这种关系的维护是非常令人头痛的,所以就有了控制反转这个概念,将对象的创建、配置等一系列操作交给 spring 去管理,我们在使用的时候只要去取就好了

4.spring 中的 IOC 容器有哪些?有什么区别?

spring 主要提供了「两种 IOC 容器」,一种是 「BeanFactory」,还有一种是 「ApplicationContext」

它们的区别就在于,BeanFactory 「只提供了最基本的实例化对象和拿对象的功能」,而 ApplicationContext 是继承了 BeanFactory 所派生出来的产物,是其子类,它的作用更加的强大,比如支持注解注入、国际化等功能

5.那 BeanFactory 和 FactoryBean 又有什么区别?

这两个是「不同的产物」

「BeanFactory 是 IOC 容器」,是用来承载对象的

「FactoryBean 是一个接口」,为 Bean 提供了更加灵活的方式,通过代理一个Bean对象,对方法前后做一些操作。

6.@Repository、@Service、@Compent、@Controller它们有什么区别?

这四个注解的「本质都是一样的,都是将被该注解标识的对象放入 spring 容器当中,只是为了在使用上区分不同的应用分层」

  • @Repository:dao层
  • @Service:service层
  • @Controller:controller层
  • @Compent:其他不属于以上三层的统一使用该注解

7.那么 DI 又是什么?

DI 就是依赖注入,其实和 IOC 大致相同,只不过是「同一个概念使用了不同的角度去阐述」

DI 所描述的「重点是在于依赖」,我们说了 「IOC 的核心功能就是在于在程序运行时动态的向某个对象提供其他的依赖对象」,而这个功能就是依靠 DI 去完成的,比如我们需要注入一个对象 A,而这个对象 A 依赖一个对象 B,那么我们就需要把这个对象 B 注入到对象 A 中,这就是依赖注入

spring 中有三种注入方式

  • 接口注入
  • 构造器注入
  • set注入

8.说说 AOP 是什么?

AOP 意为:「面向切面编程,通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术」

AOP 是 「OOP(面向对象编程) 的延续」,是 Spring 框架中的一个重要内容,是函数式编程的一种衍生范型。利用 AOP 可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。

「AOP 实现主要分为两类:」

《面试八股文》之 Spring 18卷
  • 「静态 AOP 实现」, AOP 框架「在编译阶段」对程序源代码进行修改,生成了静态的 AOP 代理类(生成的 *.class 文件已经被改掉了,需要使用特定的编译器),比如 AspectJ
  • 「动态 AOP 实现」, AOP 框架「在运行阶段」对动态生成代理对象(在内存中以 JDK 动态代理,或 CGlib 动态地生成 AOP 代理类),如 SpringAOP

spring 中 AOP 的实现是「通过动态代理实现的」,如果是实现了接口就会使用 JDK 动态代理,否则就使用 CGLIB 代理。

《面试八股文》之 Spring 18卷

「有 5 种通知类型:」

  • 「@Before」:在目标方法调用前去通知
  • 「@AfterReturning」:在目标方法返回或异常后调用
  • 「@AfterThrowing」:在目标方法返回后调用
  • 「@After」:在目标方法异常后调用
  • 「@Around」:将目标方法封装起来,自己确定调用时机

9.动态代理和静态代理有什么区别?

「静态代理」

  • 由程序员创建或由特定工具自动生成源代码,再对其编译。在程序运行前,代理类的.class文件就已经存在了
  • 静态代理通常只代理一个类
  • 静态代理事先知道要代理的是什么

「动态代理」

  • 在程序运行时,运用反射机制动态创建而成
  • 动态代理是代理一个接口下的多个实现类
  • 动态代理不知道要代理什么东西,只有在运行时才知道

10.JDK 动态代理和 CGLIB 代理有什么区别?

JDK 动态代理时业务类「必须要实现某个接口」,它是「基于反射的机制实现的」,生成一个实现同样接口的一个代理类,然后通过重写方法的方式,实现对代码的增强。

CGLIB 动态代理是使用字节码处理框架 ASM,其原理是通过字节码技术为一个类「创建子类,然后重写父类的方法」,实现对代码的增强。

11.Spring AOP 和 AspectJ AOP 有什么区别?

Spring AOP 是运行时增强,是通过「动态代理实现」

AspectJ AOP 是编译时增强,需要特殊的编译器才可以完成,是通过「修改代码来实现」的,支持「三种织入方式」

  • 「编译时织入」:就是在编译字节码的时候织入相关代理类
  • 「编译后织入」:编译完初始类后发现需要 AOP 增强,然后织入相关代码
  • 「类加载时织入」:指在加载器加载类的时候织入
《面试八股文》之 Spring 18卷
主要区别 Spring AOP AspecjtJ AOP
增强方式 运行时增强 编译时增强
实现方式 动态代理 修改代码
编译器 javac 特殊的编译器 ajc
效率 较低(运行时反射损耗性能) 较高
织入方式 运行时 编译时、编译后、类加载时

12.spring 中 Bean 的生命周期是怎样的?

SpringBean 生命周期大致分为4个阶段:

《面试八股文》之 Spring 18卷
  • 1.「实例化」,实例化该 Bean 对象
  • 2.「填充属性」,给该 Bean 赋值
  • 3.「初始化」
    • 如果实现了 Aware 接口,会通过其接口获取容器资源
    • 如果实现了 BeanPostProcessor 接口,则会回调该接口的前置和后置处理增强
    • 如果配置了 init-method 方法,]会执行该方法
  • 4.「销毁」
    • 如果实现了 DisposableBean 接口,则会回调该接口的 destroy 方法
    • 如果配置了 destroy-method 方法,则会执行 destroy-method 配置的方法

13.spring 是怎么解决循环依赖的?

《面试八股文》之 Spring 18卷

循环依赖就是说两个对象相互依赖,形成了一个环形的调用链路

spring 使用三级缓存去解决循环依赖的,其「核心逻辑就是把实例化和初始化的步骤分开,然后放入缓存中」,供另一个对象调用

  • 「第一级缓存」:用来保存实例化、初始化都完成的对象
  • 「第二级缓存」:用来保存实例化完成,但是未初始化完成的对象
  • 「第三级缓存」:用来保存一个对象工厂,提供一个匿名内部类,用于创建二级缓存中的对象

当 A、B 两个类发生循环引用时 大致流程

  • 1.A 完成实例化后,去「创建一个对象工厂,并放入三级缓存」当中
    • 如果 A 被 AOP 代理,那么通过这个工厂获取到的就是 A 代理后的对象
    • 如果 A 没有被 AOP 代理,那么这个工厂获取到的就是 A 实例化的对象
  • 2.A 进行属性注入时,去「创建 B」
  • 3.B 进行属性注入,需要 A ,则「从三级缓存中去取 A 工厂代理对象」并注入,然后删除三级缓存中的 A 工厂,将 A 对象放入二级缓存
  • 4.B 完成后续属性注入,直到初始化结束,将 B 放入一级缓存
  • 5.「A 从一级缓存中取到 B 并且注入 B」, 直到完成后续操作,将 A 从二级缓存删除并且放入一级缓存,循环依赖结束

spring 解决循环依赖有两个前提条件:

  • 1.「不全是构造器方式」的循环依赖(否则无法分离初始化和实例化的操作)
  • 2.「必须是单例」(否则无法保证是同一对象)

14.为什么要使用三级缓存,二级缓存不能解决吗?

可以,三级缓存的功能是只有真正发生循环依赖的时候,才去提前生成代理对象,否则只会「创建一个工厂并将其放入到三级缓存」中,但是不会去通过这个工厂去真正创建对象。

如果使用二级缓存解决循环依赖,意味着所有 Bean 在实例化后就要完成 AOP 代理,这样「违背了 Spring 设计的原则」,Spring 在设计之初就是在 Bean 生命周期的最后一步来完成 AOP 代理,而不是在实例化后就立马进行 AOP 代理。

15.@Autowired 和 @Resource 有什么区别?

  • 「@Resource 是 Java 自己的注解」,@Resource 有两个属性是比较重要的,分是 name 和 type;Spring 将 @Resource 注解的 name 属性解析为 bean 的名字,而 type 属性则解析为 bean 的类型。所以如果使用 name 属性,则使用 byName 的自动注入策略,而使用 type 属性时则使用 byType 自动注入策略。如果既不指定 name 也不指定 type 属性,这时将通过反射机制使用 byName 自动注入策略。

  • 「@Autowired 是spring 的注解」,是 spring2.5 版本引入的,Autowired 只根据 type 进行注入,「不会去匹配 name」。如果涉及到 type 无法辨别注入对象时,那需要依赖 @Qualifier 或 @Primary 注解一起来修饰。

16.spring 事务隔离级别有哪些?

《面试八股文》之 Spring 18卷
  • DEFAULT:采用 DB 默认的事务隔离级别
  • READ_UNCOMMITTED:读未提交
  • READ_COMMITTED:读已提交
  • REPEATABLE_READ:可重复读
  • SERIALIZABLE:串行化

17.spring 事务的传播机制有哪些?

《面试八股文》之 Spring 18卷
  • 1.「propagation_required」
    • 当前方法「必须在一个具有事务的上下文中运行」,如有客户端有事务在进行,那么被调用端将在该事务中运行,否则的话重新开启一个事务。(如果被调用端发生异常,那么调用端和被调用端事务都将回滚)
  • 2.「propagation_supports」
    • 当前方法不必需要具有一个事务上下文,但是如果有一个事务的话,它也可以在这个事务中运行
  • 3.「propagation_mandatory」
    • 表示当前方法「必须在一个事务中运行」,如果没有事务,将抛出异常
  • 4.「propagation_nested」
    • 如果当前方法正有一个事务在运行中,则该方法应该「运行在一个嵌套事务」中,被嵌套的事务可以独立于被封装的事务中进行提交或者回滚。如果封装事务存在,并且外层事务抛出异常回滚,那么内层事务必须回滚,反之,内层事务并不影响外层事务。如果封装事务不存在,则同propagation_required的一样
  • 5.「propagation_never」
    • 当方法务不应该在一个事务中运行,如果「存在一个事务,则抛出异常」
  • 6.「propagation_requires_new」
    • 当前方法「必须运行在它自己的事务中」。一个新的事务将启动,而且如果有一个现有的事务在运行的话,则这个方法将在运行期被挂起,直到新的事务提交或者回滚才恢复执行。
  • 7.「propagation_not_supported」
    • 方法不应该在一个事务中运行。「如果有一个事务正在运行,他将在运行期被挂起,直到这个事务提交或者回滚才恢复执行」

18.springBoot 自动装配原理?

《面试八股文》之 Spring 18卷
  • 1.容器在启动的时候会调用 EnableAutoConfigurationImportSelector.class 的 selectImports方法「获取一个全面的常用 BeanConfiguration 列表」

  • 2.之后会读取 spring-boot-autoconfigure.jar 下面的spring.factories,「获取到所有的 Spring 相关的 Bean 的全限定名 ClassName」

  • 3.之后继续「调用 filter 来一一筛选」,过滤掉一些我们不需要不符合条件的 Bean

  • 4.最后把符合条件的 BeanConfiguration 注入默认的 EnableConfigurationPropertie 类里面的属性值,并且「注入到 IOC 环境当中」

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
Go高并发任务调度与Goroutine池化实践
Go高并发任务调度与Goroutine池化实践

本专题围绕 Go 语言在高并发任务处理场景中的实践展开,系统讲解 Goroutine 调度模型、Channel 通信机制以及并发控制策略。内容包括任务队列设计、Goroutine 池化管理、资源限制控制以及并发任务的性能优化方法。通过实际案例演示,帮助开发者构建稳定高效的 Go 并发任务处理系统,提高系统在高负载环境下的处理能力与稳定性。

2

2026.03.10

Kotlin Android模块化架构与组件化开发实践
Kotlin Android模块化架构与组件化开发实践

本专题围绕 Kotlin 在 Android 应用开发中的架构实践展开,重点讲解模块化设计与组件化开发的实现思路。内容包括项目模块拆分策略、公共组件封装、依赖管理优化、路由通信机制以及大型项目的工程化管理方法。通过真实项目案例分析,帮助开发者构建结构清晰、易扩展且维护成本低的 Android 应用架构体系,提升团队协作效率与项目迭代速度。

24

2026.03.09

JavaScript浏览器渲染机制与前端性能优化实践
JavaScript浏览器渲染机制与前端性能优化实践

本专题围绕 JavaScript 在浏览器中的执行与渲染机制展开,系统讲解 DOM 构建、CSSOM 解析、重排与重绘原理,以及关键渲染路径优化方法。内容涵盖事件循环机制、异步任务调度、资源加载优化、代码拆分与懒加载等性能优化策略。通过真实前端项目案例,帮助开发者理解浏览器底层工作原理,并掌握提升网页加载速度与交互体验的实用技巧。

80

2026.03.06

Rust内存安全机制与所有权模型深度实践
Rust内存安全机制与所有权模型深度实践

本专题围绕 Rust 语言核心特性展开,深入讲解所有权机制、借用规则、生命周期管理以及智能指针等关键概念。通过系统级开发案例,分析内存安全保障原理与零成本抽象优势,并结合并发场景讲解 Send 与 Sync 特性实现机制。帮助开发者真正理解 Rust 的设计哲学,掌握在高性能与安全性并重场景中的工程实践能力。

187

2026.03.05

PHP高性能API设计与Laravel服务架构实践
PHP高性能API设计与Laravel服务架构实践

本专题围绕 PHP 在现代 Web 后端开发中的高性能实践展开,重点讲解基于 Laravel 框架构建可扩展 API 服务的核心方法。内容涵盖路由与中间件机制、服务容器与依赖注入、接口版本管理、缓存策略设计以及队列异步处理方案。同时结合高并发场景,深入分析性能瓶颈定位与优化思路,帮助开发者构建稳定、高效、易维护的 PHP 后端服务体系。

339

2026.03.04

AI安装教程大全
AI安装教程大全

2026最全AI工具安装教程专题:包含各版本AI绘图、AI视频、智能办公软件的本地化部署手册。全篇零基础友好,附带最新模型下载地址、一键安装脚本及常见报错修复方案。每日更新,收藏这一篇就够了,让AI安装不再报错!

116

2026.03.04

Swift iOS架构设计与MVVM模式实战
Swift iOS架构设计与MVVM模式实战

本专题聚焦 Swift 在 iOS 应用架构设计中的实践,系统讲解 MVVM 模式的核心思想、数据绑定机制、模块拆分策略以及组件化开发方法。内容涵盖网络层封装、状态管理、依赖注入与性能优化技巧。通过完整项目案例,帮助开发者构建结构清晰、可维护性强的 iOS 应用架构体系。

180

2026.03.03

C++高性能网络编程与Reactor模型实践
C++高性能网络编程与Reactor模型实践

本专题围绕 C++ 在高性能网络服务开发中的应用展开,深入讲解 Socket 编程、多路复用机制、Reactor 模型设计原理以及线程池协作策略。内容涵盖 epoll 实现机制、内存管理优化、连接管理策略与高并发场景下的性能调优方法。通过构建高并发网络服务器实战案例,帮助开发者掌握 C++ 在底层系统与网络通信领域的核心技术。

31

2026.03.03

Golang 测试体系与代码质量保障:工程级可靠性建设
Golang 测试体系与代码质量保障:工程级可靠性建设

Go语言测试体系与代码质量保障聚焦于构建工程级可靠性系统。本专题深入解析Go的测试工具链(如go test)、单元测试、集成测试及端到端测试实践,结合代码覆盖率分析、静态代码扫描(如go vet)和动态分析工具,建立全链路质量监控机制。通过自动化测试框架、持续集成(CI)流水线配置及代码审查规范,实现测试用例管理、缺陷追踪与质量门禁控制,确保代码健壮性与可维护性,为高可靠性工程系统提供质量保障。

81

2026.02.28

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Spring中文手册
Spring中文手册

共0课时 | 0.6万人学习

马士兵spring视频教程
马士兵spring视频教程

共25课时 | 9.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号