Spring和MyBatis常见面试题总结

文章目录

本文作者:夏日。主要参考:JavaGuide,同时加上网上搜索整理和个人理解总结。

1 Spring 基础

1.1 说一下你对 Spring 的理解🔥

Spring 是一款开源的轻量级 Java 开发框架,旨在提高开发人员的开发效率以及系统的可维护性。Spring框架核心特性包括:

  • IoC容器:Spring通过控制反转实现了对象的创建和对象间的依赖关系管理。开发者只需要定义好Bean及其依赖关系,Spring容器负责创建和组装这些对象。
  • AOP:面向切面编程,允许开发者定义横切关注点,例如事务管理、安全控制等,独立于业务逻辑的代码。通过AOP,可以将这些关注点模块化,提高代码的可维护性和可重用性。
  • 事务管理:Spring提供了一致的事务管理接口,支持声明式和编程式事务。开发者可以轻松地进行事务管理,而无需关心具体的事务API。
  • MVC框架:Spring MVC是一个基于Servlet API构建的Web框架,采用了模型-视图-控制器(MVC)架构。它支持灵活的URL到页面控制器的映射,以及多种视图技术。

1.2 Spring,Spring MVC,Spring Boot 之间什么关系?

Spring 包含了多个功能模块,其中最重要的是 Spring-Core(主要提供 IoC 依赖注入功能的支持) 模块, Spring 中的其他模块(比如 Spring MVC)的功能实现基本都需要依赖于该模块。

Spring MVC 是 Spring 中的一个很重要的模块,主要赋予 Spring 快速构建 MVC 架构的 Web 程序的能力。MVC 是模型(Model)、视图(View)、控制器(Controller)的简写,其核心思想是通过将业务逻辑、数据、显示分离来组织代码。

使用 Spring 进行开发各种配置过于麻烦比如开启某些 Spring 特性时,需要用 XML 或 Java 进行显式配置。于是,Spring Boot 诞生了!

Spring 旨在简化 J2EE 企业应用程序开发。Spring Boot 旨在简化 Spring 开发(减少配置文件,开箱即用!)。

Spring Boot 只是简化了配置,如果你需要构建 MVC 架构的 Web 程序,你还是需要使用 Spring MVC 作为 MVC 框架,只是说 Spring Boot 帮你简化了 Spring MVC 的很多配置,真正做到开箱即用!

1.3 Spring 框架中用到了哪些设计模式?🔥

  • 工厂设计模式 : Spring 使用工厂模式通过 BeanFactory 创建 bean 对象。
  • 代理设计模式 : Spring AOP 功能的实现。
  • 单例设计模式 : Spring 中的 Bean 默认都是单例的。
  • 模板方法模式 : Spring 中 jdbcTemplatehibernateTemplate 等以 Template 结尾的对数据库操作的类,它们就使用到了模板模式。
  • 适配器模式 : Spring MVC 中用到了适配器模式适配 Controller
  • 包装器设计模式 : 我们的项目需要连接多个数据库,而且不同的客户在每次访问中根据需要会去访问不同的数据库。这种模式让我们可以根据客户的需求能够动态切换不同的数据源。
  • 观察者模式: Spring 事件驱动模型就是观察者模式很经典的一个应用。

1.4 说说自己对于 Spring MVC 了解?

  • 视图(view): 为用户提供使用界面,与用户直接进行交互。
  • 模型(model): 代表一个存取数据的对象。模型分为两类,一类称为数据承载 Bean,一类称为业务处理 Bean。所谓数据承载 Bean 是指实体类(如:User 类),专门为用户承载业务数据的;而业务处理 Bean 则是指 Service 或 Dao 对象,专门用于处理用户提交请求的。
  • 控制器(controller): 用于将用户请求转发给相应的 Model 进行处理,并根据 Model 的计算结果向用户提供相应响应。它使视图与模型分离。

1.5 Spring MVC 的核心组件有哪些?

  • DispatcherServlet核心的中央处理器,负责接收请求、分发,并给予客户端响应。
  • HandlerMapping处理器映射器,根据 URL 去匹配查找能处理的 Handler(也就是我们平常说的 Controller 控制器) ,并会将请求涉及到的拦截器和 Handler 一起封装。
  • HandlerAdapter处理器适配器,根据 HandlerMapping 找到的 Handler ,适配执行对应的 Handler
  • Handler请求处理器,处理实际请求的处理器。
  • ViewResolver视图解析器,根据 Handler 返回的逻辑视图 / 视图,解析并渲染真正的视图,并传递给 DispatcherServlet 响应客户端

1.6 SpringMVC 工作原理了解吗?🔥

  1. 客户端(浏览器)发送请求, DispatcherServlet 拦截请求。
  2. DispatcherServlet 根据请求信息调用 HandlerMappingHandlerMapping 根据 URL 去匹配查找能处理的 Handler(也就是我们平常说的 Controller 控制器) 。
  3. DispatcherServlet 调用 HandlerAdapter 适配器执行 Handler
  4. Handler 完成对用户请求的处理后,会返回一个 ModelAndView 对象给 DispatcherServletView 是个逻辑上的 View。(如果是Spring Boot 返回 JSON 数据到这步就结束了)
  5. ViewResolver 会根据逻辑 View 查找实际的 View
  6. DispaterServlet 把返回的 Model 传给 View,也就是渲染视图。
  7. 最后把 View 返回给客户端

1.7 Spring 循环依赖了解吗,怎么解决?🔥

循环依赖是指两个或多个 Bean 之间相互持有对方的引用。

循环依赖问题在 Spring 中主要有三种情况:

  • 第一种:通过构造方法进行依赖注入时产生的循环依赖问题。
  • 第二种:在多例模式下产生的循环依赖问题。
  • 第三种:在单例模式下产生的循环依赖问题。

只有【第三种方式】的循环依赖问题被 Spring 解决了,其他两种方式在遇到循环依赖问题时,Spring 都会产生异常。Spring 解决单例模式下的循环依赖问题的主要方式是通过三级缓存解决循环依赖。

具体步骤如下:如果发生循环依赖的话,就去 三级缓存 中拿到三级缓存中存储的 ObjectFactory 并调用它的 getObject() 方法来获取这个循环依赖对象的早期引用,并且将这个早期引用放到二级缓存中,然后将这个早期引用注入到依赖,来解决循环依赖问题。

1.8 spring 三级缓存是什么?🔥

  1. 一级缓存(singletonObjects):存储的是已经完全初始化好的 bean,即完全准备好可以使用的 bean 实例。
  2. 二级缓存(earlySingletonObjects):存放早期的bean引用,已经实例化但还未完全初始化,也就是三级缓存中 ObjectFactory 产生的对象,与三级缓存配合使用可以防止 AOP 的情况下,每次调用 ObjectFactory#getObject() 都会产生新的代理对象。
    1. 确保了即使在 Bean 的创建过程中有多次对早期引用的请求,也始终只返回同一个代理对象,从而避免了同一个 Bean 有多个代理对象的问题。
  3. 三级缓存(singletonFactories):存放 ObjectFactory 对象,这些对象可以生成早期的 bean 引用。当一个 bean 正在创建过程中,如果它被其他 bean 依赖,那么这个正在创建的 bean 就会通过这个 ObjectFactory 来创建一个早期引用,从而解决循环依赖的问题。

1.9 @Lazy 能解决多例模式下的循环依赖吗?

可以解决。 @Lazy 用来标识类是否需要延迟加载,可以作用在类上、方法上、构造器上、方法参数上、成员变量中。

如果一个 Bean 被标记为延迟加载,那么它不会在 Spring IoC 容器启动时立即实例化,而是在第一次被请求时才创建。这可以帮助减少应用启动时的初始化时间,也可以用来解决循环依赖问题。

通过 @Lazy 可以解决多例模式下的循环依赖,关键点就在于对 A 中的属性 B 进行注入时,注入的是 B 的代理对象,因此不会循环依赖。之前说的发生循环依赖是因为在对 A 中的属性 B 进行注入时,注入的是 B 对象,此时又会去初始化 B 对象,发现 B 又依赖了 A,因此才导致的循环依赖。

2 Spring IoC 和 AOP

2.1 谈谈对于 Spring IoC 的了解🔥

IoC 也就是控制反转,IoC 的思想就是将原本在程序中手动创建对象的控制权,交由 Spring 框架来管理。依赖注入(DI)是实现这种思想的一种方式。传统开发过程中,我们需要通过new关键字来创建对象。使用IoC思想开发的话,我们不通过new关键字创建对象,而是通过IoC容器来获取对象。将对象之间的相互依赖关系交给 IoC 容器来管理,并由 IoC 容器完成对象的注入。通过IoC的方式,可以大大降低对象之间的耦合度。

2.2 IOC和AOP是通过什么机制来实现的?🔥

Spring IOC 实现机制

  • 反射: Spring IOC容器利用Java的反射机制动态地加载类、创建对象实例及调用对象方法,从而实现灵活的对象实例化和管理。
  • 依赖注入: IOC的核心概念是依赖注入,也就是 IOC容器负责依赖关系。Spring 提供了多种方式来进行依赖注入,比如通过构造函数注入字段注入Setter 方法注入。
  • 设计模式 - 工厂模式: IOC容器采用工厂模式来管理对象的创建和生命周期。
  • 容器实现:Spring IOC容器是实现IOC的核心,通常使用BeanFactory或ApplicationContext来管理Bean。BeanFactory是IOC容器的基本形式,提供基本的IOC功能;ApplicationContext是BeanFactory的扩展,并提供更多企业级功能。

Spring AOP 实现机制

Spring AOP的实现依赖于动态代理技术。动态代理是在运行时动态生成代理对象,而不是在编译时。它允许开发者在运行时指定要代理的接口和行为,从而实现在不修改源码的情况下增强方法的功能。

Spring AOP支持两种动态代理:

  • 基于JDK的动态代理:这种方式需要代理的类实现一个或多个接口。基于Java的反射机制和接口,代理对象在运行时实现目标类的接口,并通过反射调用目标方法。
  • 基于CGLIB的动态代理:可以代理没有实现接口的类。CGLIB通过继承目标类并动态生成一个子类来创建代理对象。CGLIB通过使用字节码生成库(如ASM)来动态生成目标类的子类,并通过方法拦截机制来代理目标对象的方法调用。
  • 因为CGLIB通过生成字节码创建代理对象,性能通常比JDK代理稍慢,尤其是在生成代理对象的过程中会涉及较大的开销。然而,生成的代理类调用方法的速度更快。

2.3 如果让你设计一个SpringIoc,你觉得会从哪些方面考虑这个设计?

  • Bean的生命周期管理:需要设计Bean的创建、初始化、销毁等生命周期管理机制,可以考虑使用工厂模式和单例模式来实现。
  • 依赖注入:需要实现依赖注入的功能,包括属性注入、构造函数注入、Setter 方法注入等,可以考虑使用反射机制和XML配置文件来实现。
  • Bean的作用域:需要支持多种Bean作用域,比如单例、多例等,可以考虑使用Map来存储不同作用域的Bean实例。
  • AOP功能的支持:需要支持AOP功能,可以考虑使用动态代理机制和切面编程来实现。
  • 异常处理:需要考虑异常处理机制,包括Bean创建异常、依赖注入异常等,可以考虑使用try-catch机制来处理异常。
  • 配置文件加载:需要支持从不同的配置文件中加载Bean的相关信息,可以考虑使用XML、注解或者Java配置类来实现。

2.4 谈谈自己对于 AOP 的了解🔥

Spring AOP 是 Spring 框架中的一个重要模块,用于实现面向切面编程。

我们知道,Java 是一门面向对象编程的语言,在 OOP 中最小的单元就是“Class 对象”,但是在 AOP 中最小的单元是“切面”。一个“切面”可以包含很多种类型和对象,对它们进行模块化管理,例如事务管理。

在面向切面编程的思想里面,把功能分为两种

  • 核心业务:登陆、注册、增、删、改、查、都叫核心业务
  • 周边功能:日志、事务管理这些次要的为周边业务

在面向切面编程中,核心业务功能和切面功能是分别独立进行开发,两者不是耦合的,然后把切面功能和核心业务功能 “编织” 在一起,这就叫 AOP。

AOP 能够将那些与业务无关,却为业务模块所共同调用的逻辑或责任(例如事务处理、日志管理、权限控制等)封装起来,便于减少系统的重复代码降低模块间的耦合度,并有利于未来的可拓展性和可维护性

在 AOP 中有以下

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值