Spring最新核心高频面试题(持续更新)

1 什么是Spring框架

Spring框架是一个开源的Java应用程序开发框架,它提供了很多工具和功能,可以帮助开发者更快地构建企业级应用程序。通过使用Spring框架,开发者可以更加轻松地开发Java应用程序,并且可以更加灵活地组织和管理应用程序中的对象和组件

Spring框架的核心思想是控制反战(IOC)、依赖注入(DI)和面向切面编程(AOP)。控制反转(IOC)是将实例的控制权交给外部容器,统一管理。依赖注入(DI)可以帮助我们更好地组织和管理应用程序中的对象,使得应用程序更加松耦合,易于扩展和维护。面向切面编程(AOP)可以帮助我们更好地管理应用程序中的横切关注点,比如日志、事务、安全等,使得应用程序更加模块化和可维护。

除了核心容器以外,Spring框架还提供了很多其他的组件和框架,比如Spring MVC可以帮助我们更加轻松地开发Web应用程序,Spring JDBC可以帮助我们更加轻松地访问和操作数据库,Spring ORM可以帮助我们更加轻松地使用ORM框架等等。

总的来说,Spring框架可以帮助我们更加轻松地开发Java应用程序,提高开发效率,减少代码冗余和重复,使得应用程序更加灵活和易于维护。

2 Spring包含哪些模块

Spring框架包含了很多模块,以下是一些重要的Spring模块:

Spring Core:Spring框架的核心模块,提供了依赖注入(DI)和控制反转(IoC)的功能,用于管理对象之间的依赖关系。

Spring MVC:基于MVC(Model-View-Controller)模式的Web框架,提供了用于处理请求、响应以及Web应用程序其他方面的API。

Spring Data:Spring框架的数据访问层模块,提供了通用的数据访问抽象层和一些特定数据访问技术的实现,如JPA、Hibernate等。

Spring Security:Spring框架的安全模块,提供了基于Spring框架的认证和授权功能,可以保护Web应用程序免受各种攻击。

Spring Integration:Spring框架的集成模块,提供了一些集成技术的实现,如消息队列、Web服务、FTP等。

Spring Batch:Spring框架的批处理模块,提供了处理大规模数据批处理的功能,包括事务处理、并发处理、失败处理等。

Spring Cloud:Spring框架的云原生模块,提供了在云环境下构建微服务应用程序所需的一些基础设施和工具,如服务注册、配置中心、断路器等。

除了以上列举的模块,Spring框架还包含了很多其他的模块,比如Spring WebFlux、Spring Test、Spring WebSocket等,每个模块都提供了一些特定的功能和工具,可以帮助开发者更加方便地开发Java应用程序。

3 什么是IOC

IoC(Inversion of Control)是一种设计模式,它将对象之间的依赖关系的管理交给框架来处理,从而实现对象之间的松耦合和可维护性。

传统的编程模式中,对象之间的依赖关系是由对象自己来管理的,当对象A需要对象B的协助完成某个功能时,对象A会主动创建对象B,然后在适当的时候调用对 象B的方法。这种方式会导致对象之间的依赖关系紧密耦合,使得代码难以维护和扩展。

在Spring框架中,实现IoC的方式是通过依赖注入(Dependency Injection,DI)来实现的。DI有三种实现方式:

  • 构造函数注入(Constructor Injection):通过构造函数来注入依赖对象。

  • 属性注入(Setter Injection):通过setter方法来注入依赖对象。

  • 接口注入(Interface Injection):通过接口方法来注入依赖对象。

定义的Bean会被IOC容器读取并加载。当需要使用某个Bean时,容器会创建指定的Bean。

依赖注入:当IOC容器创建一个Bean时,它会检查该Bean所依赖的其他Bean是否已经创建,如果已经创建,则会将依赖的Bean注入到该Bean中,否则会等待所依赖的Bean创建完成后再注入依赖。(依赖注入是注入Bean内部的属性)

4 什么是AOP? 有哪些AOP的概念?

AOP(Aspect-Oriented Programming)是一种编程思想,它通过将应用程序分解成多个切面,来实现对应用程序进行横向切割的目的,从而实现代码的复用和系统的解耦。

AOP的核心思想是将与业务逻辑无关的代码,如日志、事务、异常处理等,从业务逻辑代码中分离出来,形成独立的模块,以便于复用和维护。

AOP的一些概念如下:

  • 切面(Aspect):切面是一个模块化的横切关注点,它通过对某个点进行拦截,来实现对目标对象的增强。(切面中存放的是通知等方法的)

  • 连接点(Join Point):连接点是在应用程序执行过程中能够插入切面的点,例如方法调用或异常处理等。(作用于要增强的方法)

  • 切入点(Pointcut):切入点是一组连接点的集合,它定义了在哪些连接点处应用切面。

  • 通知(Advice):通知是切面在连接点上执行的操作,例如在方法调用前、方法调用后、方法返回时或方法抛出异常时执行的操作。

  • 织入(Weaving):织入是将切面应用到目标对象并创建新的代理对象的过程。织入可以在编译时、类加载时或运行时进行。

  • 目标对象(Target Object):目标对象是应用程序中需要被增强的对象。

  • 代理对象(Proxy Object):代理对象是一个中间件对象,它拦截对目标对象的访问并调用切面提供的通知。

通过AOP的概念,我们可以将应用程序按照不同的横向关注点进行切割,并将与业务逻辑无关的代码分离出来,从而提高应用程序的可维护性和可扩展性。常见的AOP框架有Spring AOP和AspectJ。

5 AOP 有哪些应用场景?

AOP(Aspect-Oriented Programming)可以在许多场景下被应用。以下是一些AOP的应用场景:

  • 日志记录:在方法调用前后记录日志,用于排查错误和分析系统性能。

  • 安全性控制:控制用户对系统中某些资源或方法的访问权限,确保系统安全。

  • 事务管理:在方法调用前后开启、提交或回滚事务,确保数据的一致性和完整性。

  • 缓存管理:通过在方法调用前检查缓存中是否有目标对象的缓存结果,减少系统的响应时间和网络开销。

  • 性能监控:记录方法调用的时间、次数和异常等信息,以便于分析系统性能。

  • 异常处理:在方法调用过程中捕获异常并记录或通知开发人员,以便于及时处理异常情况。

  • 数据验证:在方法调用前对输入参数进行验证,确保输入数据的正确性和合法性。

  • 代码复用:将与业务逻辑无关的代码抽离出来,以便于复用和维护。

6 AOP Advice通知的类型?

在AOP(Aspect-Oriented Programming)中,通知(Advice)是在切面(Aspect)中定义的一些方法,用于在连接点(Join Point)处执行特定的操作。通知可以分为以下几种类型:

  • 前置通知(Before Advice):在连接点之前执行的通知,例如在方法调用前记录日志或开启事务等。

  • 后置通知(After Advice):在连接点之后执行的通知,例如在方法调用后记录日志或提交事务等。

  • 返回通知(After Returning Advice):在方法返回结果之后执行的通知,例如在方法调用后记录返回结果或关闭资源等。

  • 异常通知(After Throwing Advice):在方法抛出异常时执行的通知,例如在方法调用抛出异常时记录异常信息或回滚事务等。

  • 环绕通知(Around Advice):在方法调用之前和之后都可以执行的通知,它可以自由控制方法调用前后的逻辑,例如在方法调用前记录日志或在方法调用后提交事务等。

以上通知类型都是用于在连接点处执行特定的操作,并通过切面将这些通知应用到目标对象中。这些通知类型可以根据实际业务需求进行组合,从而实现对目标对象的增强,提高应用程序的可维护性和可扩展性。

7 Spring中的bean的作用域有哪些?

在Spring中,Bean的作用域(Scope)指定了在容器中创建的Bean实例的生命周期,不同的作用域决定了Bean实例的可见范围和生命周期长度。Spring框架支持以下五种Bean作用域:

  • singleton(单例):在整个应用中只创建一个Bean实例,并在容器启动时就创建,以后每次请求都返回同一个实例。

  • prototype(原型):每次请求都会创建一个新的Bean实例,适用于一些状态不可共享的Bean。

  • request(请求):在每个HTTP请求中创建一个Bean实例,该Bean实例仅在当前请求中有效,对于不同的请求,会创建不同的Bean实例。

  • session(会话):在每个HTTP Session中创建一个Bean实例,该Bean实例仅在当前Session中有效,对于不同的Session,会创建不同的Bean实例。

  • global-session(全局会话):在基于portlet的web应用中使用,该作用域仅在基于portlet的web应用中有效,一个portlet的多个请求共享一个Bean实例。

其中,单例(singleton)是默认的作用域,当没有指定作用域时,Spring会默认将Bean作为单例。除了全局会话作用域,其他四种作用域都只适用于Web应用。在Spring中,可以通过在Bean定义中指定scope属性来指定Bean的作用域。

在注解中,可以使用@Scope注解来指定Bean的作用域,如下所示:

java 复制代码
@Component
@Scope("prototype")
public class ExampleBean {
    // ...
}

**注:**需要注意的是,在单例作用域中,如果Bean有状态(stateful),则需要考虑线程安全问题,否则可能会导致多线程并发访问出现问题。因此,对于有状态的Bean,建议使用原型作用域(prototype)。

8 Spring中的单例bean的线程安全问题

在Spring中,单例Bean的线程安全问题是需要考虑的。由于单例Bean在容器启动时就会被创建,因此所有的请求都会共享同一个Bean实例。如果Bean有状态(stateful),即Bean的属性会随着请求的处理而改变,那么在多线程并发访问的情况下,就需要考虑线程安全问题。

在单例Bean中,如果有多个线程同时访问Bean实例并且Bean实例中有共享的数据,那么就可能出现数据不一致的情况,这是因为多个线程会竞争共享数据的访问权,导致数据出现冲突。为了解决这个问题,需要在多线程环境下保证Bean实例的线程安全。

有多种方式可以保证Spring中的单例Bean的线程安全:

  1. 在bean对象中尽量避免定义可变的成员变量(不太现实)。

  2. 在类中定义一个ThreadLocal成员变量,将需要的可变成员变量保存在ThreadLocal中(推荐的一种方式)。

需要注意的是,Spring框架本身并不提供对单例Bean的线程安全保证,因此需要在编写代码时自行考虑和实现线程安全的措施。

9 spring bean 容器的生命周期是什么

此处先赋流程图片更为清晰,详细整理之后再出。


10 对于Spring MVC的了解

Spring MVC是基于MVC(Model-View-Controller)设计模式实现的一种Web应用程序开发框架。它是Spring Framework的一个重要组成部分,提供了一个灵活、松耦合、可扩展、高效的Web开发框架。

在Spring MVC中,M代表模型(Model),即数据模型;V代表视图(View),即用户界面;C代表控制器(Controller)

Spring MVC下我们一般把后端项目分为Service层(处理业务)、Dao层(数据库操作)、Entity层(实体类)、Controller层(控制层,返回数据给前台页面)。

11 SpringMvc的工作原理

Spring MVC的工作原理可以分为以下几个步骤:

  1. 客户端发送请求,请求被前端控制器DispatcherServlet截获。

  2. DispatcherServlet查询处理器映射HandlerMapping,根据请求URI找到对应的处理器Controller。

  3. HandlerAdapter将请求发送给处理器Controller进行处理,Controller根据请求参数处理业务逻辑,调用业务逻辑层的Service。

  4. Service处理业务逻辑,返回数据给Controller。

  5. Controller将数据封装为ModelAndView对象,其中Model表示数据模型,View表示视图名称。

  6. DispatcherServlet查询视图解析器ViewResolver,根据视图名称找到对应的视图View。

  7. View渲染模型数据,将视图返回给DispatcherServlet。

  8. DispatcherServlet将视图发送给客户端,完成请求响应。

在这个过程中,Spring MVC的核心组件包括:

  1. DispatcherServlet:前端控制器,负责拦截所有请求并进行处理。

  2. HandlerMapping:处理器映射,用于将请求映射到对应的处理器。

  3. HandlerAdapter:处理器适配器,用于将请求发送给处理器进行处理。

  4. Controller:处理器,用于处理具体的业务逻辑。

  5. Service:业务逻辑层,负责处理具体的业务逻辑。

  6. Model:数据模型,用于封装业务逻辑返回的数据。

  7. View:视图,用于展示数据给用户。

  8. ViewResolver:视图解析器,用于将视图名称解析为实际的视图对象。

Spring MVC的工作流程是非常灵活的,可以根据实际需求进行定制和扩展。开发人员可以自定义处理器映射、处理器适配器、视图解析器等组件,以满足不同的业务场景需求。同时,Spring MVC也提供了很多现成的插件和组件,如国际化插件、文件上传插件等,可以大大提高开发效率。

12 Spring框架中用到了哪些设计模式

Spring框架是一个非常重要的开源框架,它涉及到许多设计模式,以下是Spring框架中使用的一些设计模式:

单例模式:Spring框架中的bean默认是单例的,可以通过配置更改其作用域。单例模式保证了在整个应用程序中只有一个实例。

工厂模式:Spring框架中的BeanFactory是一个工厂模式的典型实现。BeanFactory负责实例化并管理应用程序中的对象。

代理模式:Spring框架中的AOP(面向切面编程)机制是通过代理模式来实现的。Spring中使用代理对象对目标对象进行包装,从而实现对目标对象的增强。

观察者模式:Spring框架中的事件驱动机制就是一个观察者模式的实现。事件源产生事件后,会通知已经注册的监听器进行处理。

模板方法模式:Spring框架中的JdbcTemplate是一个典型的模板方法模式的实现。JdbcTemplate定义了一系列操作数据库的基本方法,而具体的实现则由其子类完成。

适配器模式:Spring框架中的HandlerAdapter就是一个适配器模式的典型实现。HandlerAdapter负责将请求发送给处理器进行处理,从而使得不同类型的处理器可以被统一处理。

除了以上这些设计模式,Spring框架还使用了许多其他的设计模式,如策略模式、装饰器模式、命令模式等。这些设计模式的使用,使得Spring框架具有了更好的灵活性、可扩展性和可维护性。

13 Spring事务中的隔离级别有哪几种?

在Spring事务中,隔离级别用来描述并发事务之间的关系,它规定了一个事务对于数据的读取能够具有的隔离程度。Spring框架中提供了五个隔离级别:

  1. Isolation.DEFAULT:默认隔离级别,由底层的数据库驱动决定隔离级别,通常为数据库的默认隔离级别。

  2. Isolation.READ_UNCOMMITTED:该隔离级别表示一个事务可以读取另一个事务修改但未提交的数据。该级别可以产生脏读、不可重复读和幻读的问题。

  3. Isolation.READ_COMMITTED:该隔离级别表示一个事务只能读取另一个事务已经提交的数据。该级别可以避免脏读问题,但不可重复读和幻读问题仍然可能发生。

  4. Isolation.REPEATABLE_READ:该隔离级别表示一个事务在执行过程中多次读取同一数据集时,其结果是一致的。该级别可以避免脏读和不可重复读问题,但仍然可能发生幻读问题。

  5. Isolation.SERIALIZABLE:该隔离级别表示一个事务在执行过程中对于数据的修改会进行排队,即串行化执行,从而避免了脏读、不可重复读和幻读问题,但也降低了并发性能。

不同的隔离级别在解决并发事务问题时采用了不同的策略,为了保证应用程序数据的一致性和正确性,在选择隔离级别时需要根据具体的业务场景和需求进行选择。

14 Spring事务中有哪几种事务传播行为?

在Spring事务中,事务的传播行为指的是在一个事务方法调用另一个事务方法时,另一个事务方法如何处理事务的行为。Spring事务支持以下七种传播行为:

  1. PROPAGATION_REQUIRED(默认值):如果当前存在事务,则在该事务中执行;否则,创建一个新的事务并在其中执行方法。

  2. PROPAGATION_SUPPORTS:支持当前事务,如果当前没有事务,就以非事务方式执行。

  3. PROPAGATION_MANDATORY:强制执行当前事务,如果当前没有事务,则抛出异常。

  4. PROPAGATION_REQUIRES_NEW:创建新的事务,并在新事务中执行方法,如果当前存在事务,则暂停当前事务。

  5. PROPAGATION_NOT_SUPPORTED:以非事务方式执行方法,如果当前存在事务,则暂停当前事务。

  6. PROPAGATION_NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。

  7. PROPAGATION_NESTED:如果当前存在事务,则在嵌套事务中执行;否则,执行与PROPAGATION_REQUIRED相同的操作。嵌套事务是当前事务的子事务,并与当前事务共享一部分数据源连接。如果嵌套事务失败,则仅回滚嵌套事务,而不会回滚当前事务。如果当前事务失败,则嵌套事务和当前事务都将被回滚。

这些传播行为可以使用@Transactional注解中的propagation属性来指定。

15 Spring事务什么时候会失效

spring事务的原理是AOP,进行了切面增强,那么失效的根本原因是这个AOP不起作用了!常见情况有如下几种

  1. 发生自调用,类里面使用this调用本类的方法(this通常省略),此时这个this对象不是代理类,而是UserService对象本身!解决方法很简单,让那个this变成UserService的代理类即可!

  2. 方法不是public的:@Transactional只能⽤于public的方法上,否则事务不会生效,如果要用在非public方法上,可以开启 AspectJ 代理模式。

    例如:如果某个方法是private的,那么@Transactional也会失效,因为底层cglib是基于父子类来实现的,子类是不能重载父类的private方法的,所无法很好的利用代理,也会导致@Transactianal失效

  3. 数据库不支持事务。

  4. 没有被spring管理。

  5. 异常被吃掉,事务不会回滚(或者抛出的异常没有被定义,默认为RuntimeException)。

16 Spring中的事务是如何实现的

  1. Spring事务底层是基于数据库事务和AOP机制的
  2. 首先对于使用了@Transactional注解的Bean,Spring会创建一个代理对象作为Bean
  3. 当调用代理对象的方法时,会先判断该方法上是否加了@Transactional注解
  4. 如果加了,那么则利用事务管理器创建一个数据库连接
  5. 并且修改数据库连接的autocommit属性为false,禁止此连接的自动提交,这是实现Spring事务非常重要的一步
  6. 然后执行当前方法,方法中会执行sql
  7. 执行完当前方法后,如果没有出现异常就直接提交事务
  8. 如果出现了异常,并且这个异常是需要回滚的就会回滚事务,否则仍然提交事务
  9. Spring事务默认的隔离级别对应的就是数据库的隔离级别
  10. Spring事务的传播机制是Spring事务自己实现的,也是Spring事务中最复杂的
  11. Spring事务的传播机制是基于数据库连接来做的,一个数据库连接一个事务,如果传播机制配置为需要新开一个事务,那么实际上就是新建立一个数据库连接,在此新数据库连接上执行sql

17 Spring启动流程

在创建Spring容器,也就是启动Spring时:

  1. ⾸先会进行扫描,扫描得到所有的BeanDefinition对象,并存在一个Map中
  2. 然后筛选出非懒加载的单例BeanDefinition进行创建Bean,对于多例Bean不需要在启动过程中去进行创建,对于多例Bean会在每次获取Bean时利用BeanDefinition去创建
  3. 利用BeanDefinition创建Bean就是Bean的创建生命周期,这期间包括了合并BeanDefinition、推断构造方法、实例化、属性填充、初始化前、初始化、初始化后等步骤,其中AOP就是发⽣在初始化后这⼀步骤中
  4. 单例Bean创建完了之后,Spring会发布一个容器启动事件
  5. Spring启动结束
  6. 在源码中会更复杂,比如源码中会提供一些模板方法,让子类来实现,比如源码中还涉及到一些BeanFactoryPostProcessor和BeanPostProcessor的注册,Spring的扫描就是通过BenaFactoryPostProcessor来实现的,依赖注入就是通过BeanPostProcessor来实现的
  7. 在Spring启动过程中还会去处理@Import等注解
相关推荐
2202_7544215412 分钟前
生成MPSOC以及ZYNQ的启动文件BOOT.BIN的小软件
java·linux·开发语言
蓝染-惣右介14 分钟前
【MyBatisPlus·最新教程】包含多个改造案例,常用注解、条件构造器、代码生成、静态工具、类型处理器、分页插件、自动填充字段
java·数据库·tomcat·mybatis
小林想被监督学习15 分钟前
idea怎么打开两个窗口,运行两个项目
java·ide·intellij-idea
HoneyMoose17 分钟前
IDEA 2024.3 版本更新主要功能介绍
java·ide·intellij-idea
我只会发热19 分钟前
Java SE 与 Java EE:基础与进阶的探索之旅
java·开发语言·java-ee
是老余20 分钟前
本地可运行,jar包运行错误【解决实例】:通过IDEA的maven package打包多模块项目
java·maven·intellij-idea·jar
crazy_wsp20 分钟前
IDEA怎么定位java类所用maven依赖版本及引用位置
java·maven·intellij-idea
.Ayang23 分钟前
tomcat 后台部署 war 包 getshell
java·计算机网络·安全·web安全·网络安全·tomcat·网络攻击模型
一直学习永不止步28 分钟前
LeetCode题练习与总结:最长回文串--409
java·数据结构·算法·leetcode·字符串·贪心·哈希表
hummhumm42 分钟前
第 22 章 - Go语言 测试与基准测试
java·大数据·开发语言·前端·python·golang·log4j