• Spring面试题(2022)


    在这里插入图片描述

    1、说说你对spring的理解,或者说下什么是spring?

    分析:主要考察求职者对spring的整体掌握度,附带考察求职者思维缜密度、表达能力等,面对这类半开放型题目,我们只需要围着理论依据+实际使用经验,展开描述即可,千万不要去背官方的甲骨文,要附带自己的理解和见解。

    答:spring是一款主流的非侵入式设计、轻量级web框架,最大特点是面向Java bean编程,降低了类之间的耦合性,
    其IOC、DI是spring 容器的核心,为bean提供了容身之处以及帮我们管理对象及其依赖关系,也为spring后续发展奠定基石,
    同时还集成了优秀理念AOP、MCV等,主要包含CORE、ORM、ContextWebWeb MVC、AOP、DAO等组件,一定程度上简化了web开发。
    
    • 1
    • 2
    • 3

    2、说说spring都有哪些模块(spring的模块有哪些)?

    分析:主要考察求职者对spring 各模块熟悉程度

    答:Spring Core:主要提供IOC和DI功能,是其他模块的基石。

    Spring AOP:提供面向切面的编程实现,支持JDK与CGLIB

    Spring JDBC:Java数据库连接

    Spring JMS:Java消息服务

    Spring ORM:支持扩展Hibernate、mybatis等ORM工具

    Spring Web:为创建Web应用程序提供支持

    Spring Test:提供了对JUnit和TestNG测试的支持

    Spring tx:事务管理

    3、怎么理解spring的ioc(对spring ioc的理解和使用)?

    分析:考察对spring ioc的理解,要回答出什么是ioc,spring怎么实现的ioc

    答:理解:ioc官方释义为控制反转,按照我的理解就是转让控制权,就拿创建Java对象来说,没有ioc之前,我们创建对象,需要显示的new,再通过构造参数、get、set赋值,然后再使用,有了spring ioc之后,我们就不需要亲力亲为,我们只需要告诉spring要用哪个对象即可,不用我们在代码里new了,对象的控制权由用户转让给了spring容器。

    使用:使用spring ioc 主要分为以下两个步骤:

    1、指定需要放入spring容器中的bean,spring提供了xml + bean标签和注解两种方式供我们使用,指定后,spring会通收集对象信息封装成BeanDefinition,然后通过过反射创建bean,最后放入容器里供我们使用

    2、指定需要使用spring容器的哪个bean。spring提供了Autowired(按类型注入)注解,同时支持jdk的Resource(按名称注入)注解。

    4、Spring的Bean是如何创建的?

    分析:考察对spring bean创建过程的掌握,出现关键词 BeanDefinitionReader、BeanDefinition、BeanDefinitionWrapper、反射、一级缓存

    答:1、根据Context类型(xml、注解)初始化BeanDefinitionReader,通过BeanDefinitionReader确认哪些Bean需要被初始化,然后将一个个的bean信息封装层BeanDefinition,最后在包装成BeanDefinitionWrapper,放入到BeanDefinitionRegister对应map中。

    2、遍历所有BeanDefinition,按照 实例化-> 依赖注入->初始化->AOP的顺序通过反射去创建bean对象

    3、将创建完成的Bean放入到一级缓存中存储,供用户使用。

    5、spring注入bean的方式有哪些(列举下你使用过的注入Bean的方式)?

    ①配置类: @Configuration+@Bean
    
    ②注解配合:@Component + @ComponentScan
    
    ③实现ImportSelector接口往spring容器中批量注入Bean
    
    ④实现ImportBeanDefinitionRegistrar接口,将bean封装成BeanDfinition往容器中注入,从而实现注入bean
    
    ⑤实现FactoryBean接口可以往Spring容器中自定义Bean
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    6、说说bean的生命周期?

    分析:考察对bean的生命周期掌握,springBean的生命周期就是bean的创建过程,按照这个过程说出来就好

    答:springBean的生命周期就是bean的创建过程,按照大的流程分的话为:实例化->属性注入->初始化->销毁,spring为了用户能更好的管理bean的生命周期,因此在这4个步骤中开放了大量的接口,让用户可以对bean的一些行为或者属性进行变更,因此完整的Bean的生命周期如下:

    • 1、实例化
      实例化一个Bean,即new。
    • 2、IOC依赖注入
      按照Spring上下文对实例化的Bean进行配置。
    • 3、setBeanName实现
      如果这个Bean已经实现了BeanNameAware接口,就会调用它实现的setBeanName(String)方法,此处传递的是Spring配置文件中Bean的id值。
    • 4、setBeanFactory实现
      如果这个Bean实现了BeanFactoryAware接口,会调用它实现的setBeanFactory(BeanFactory)方法,传递的是Spring工厂自身。
    • 5、setApplicationContext实现
      如果这个Bean实现了ApplicationContextAware接口,会调用它实现的setApplicationContext(ApplicationContext)方法,传递的是Spring的上下文。
    • 6、postProcessBeforeInitialization实现-初始化预处理
      如果这个Bean实现了BeanPostProcessor接口,将会调用它实现的postProcessBeforeInitialization(Object obj,String s)方法。BeanPostProcessor被用作Bean内容修改,并且由于这个是在Bean初始化结束的时候调用的这个方法,也可以被用于内存或缓存技术。
    • 7、init-method
      如果这个bean在Spring配置文件中配置了init-method属性,会自动调用其配置的初始化方法
    • 8、postProcessAfterInitialization
      如果这个Bean实现了BeanPostProcessor接口,将会调用它实现的postProcessAfterInitialization(Object obj,String s)方法。
      以上工作完成以后就可以应用这个Bean了。
    • 9、Destory过期自动清理
      当Bean不再需要时,如果这个Bean实现了DisposableBean这个接口,会调用其实现的.destory()方法
    • 10、destory-method
      如果这个bean在Spring配置文件中配置了destory-method属性,会自动调用其配置的销毁方法

    在这里插入图片描述

    7、Spring常用的设计模式有哪些?

    分析:考察对设计模式的理解,spring 用到的设计模式

    答:模板方法设计模式Spring中jdbcTemplate、hibernateTemplate等以Template结尾的对数据库操作的 类,
    它们就使用到模板模式。

    单例设计模式Spring中bean的默认作用域就是singleton。spring的一级缓存就是使用的容器式单例

    代理设计模式Spring AOP就是基于动态代理的。如果要代理的对象,实现了某个接口,那么Spring AOP 会使用JDK Proxy,去创建代理对象,而对于没有实现接口的对象,就无法使用JDK Proxy去进行代理了,这 时候Spring AOP会使用Cglib,这时候Spring AOP会使用Cglib生成一个被代理对象的子类来作为代理。

    工厂设计模式Spring使用工厂模式可以通过BeanFactory或ApplicationContext创建bean对象

    观察者设计模式Spring事件驱动模型就是观察者模式很经典的应用。 spring的事件流程:

      1)定义一个事件: 实现一个继承自 ApplicationEvent,并且写相应的构造函数 
      2)定义一个事件监听者:实现 ApplicationListener 接口,重写 onApplicationEvent() 方法 
      3)使用事件发布者发布消息: 可以通过 ApplicationEventPublisherpublishEvent() 方法发布消息
    
    • 1
    • 2
    • 3

    策略设计模式Spring 框架的资源访问接口就是基于策略设计模式实现的

    装饰者设计模式:装饰者设计模式可以动态地给对象增加些额外的属性或行为。相比于使用继承,
    装饰者 模式更加灵活 Spring 中配置DataSource的时候,DataSource可能是不同的数据库和数据源。
    我们能否根据客户的需求在 少修改原有类的代码下切换不同的数据源?这个时候据需要用到装饰者模式。

    适配器设计模式:适配器模式使得接口不兼容的那些类可以一起工作,其别名为包装器 在Spring MVC中,
    DispatcherServlet根据请求信息调用HandlerMapping,解析请求对应的Handler,解析 到对应的Handler
    (也就是我们常说的Controller控制器)后,开始由HandlerAdapter适配器处理

    8、BeanFactory和Context(ApplicationContext)的区别

    分析:考察BeanFactory与Context的区别,需要掌握BeanFactory,与Context,BeanFactory是bean管理的最基础类,功能最简单。

    答:因为 ApplicationContext 包含 BeanFactory 的所有功能,所以通常建议在普通BeanFactory中使用。 BeanFactory :延迟注入,相比于ApplicationContext 来说会占用更少的内存,程序启动速度更快。ApplicationContext :容器启动的时候,不管你用没用到,一次性创建所有 bean 。BeanFactory 仅提供了 最基本的依赖注入支持,ApplicationContext 扩展了 BeanFactory ,除了有BeanFactory的功能还有额外更多 功能,所以一般开发人员使ApplicationContext会更多

    9、spring是如何解决循环依赖的?

    什么是循环依赖

    从字面上来理解就是A依赖B的同时B也依赖了A,就像下面这样
    在这里插入图片描述
    体现到代码层次就是这个样子

    @Component
    public class A {
        // A中注入了B
        @Autowired
        private B b;
    }
    
    @Component
    public class B {
        // B中也注入了A
        @Autowired
        private A a;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    在这里插入图片描述在这里插入图片描述

    在这里插入图片描述

    10、spring能解决那些循环依赖、不能解决那些循环依赖,为什么?

    答:①构造函数循环依赖(无法解决)

    首先要解决循环依赖就是要先实例化,然后放入三级缓存暴露出来,那么如果是构造函数这一步循环依赖, 实例化的时候就会产生无限递归创建,所以不能别解决 如果是延迟加载的话可以解决(另当别论)

    ②setter方式的多例的循环依赖(无法解决):

    如果是多例的,在容器初始化的时候,不会去创建,所以早期没有放入到三级缓存中暴露出来,所以无法解 决循环依赖,会报错

    ③setter方式的单例循环依赖(A依赖B,B依赖A):

    A与B循环依赖,都要被代理的情况 1.A实例化->A放入三级缓存->依赖注入B->B实例化->B放入三级缓存->依赖注入a->去三级缓存拿a的代理 ->把代理的A放入二级->返回a的代理注入到B->b初始化->走后置通知获得代理b->B的代理放入一级缓存、 ->原生a依赖注入b->A初始化->后置通知,不走代理返回原生A->再偷天换日->放入一级缓存

    11、说说对spring AOP的理解和使用?

    分析:考察对spring理解和使用,可以围绕 aop的概念、实现方式、springAop支持的方式回答

    答:aop是一种面向切面编程的思想,是对oop思想的补充,是将多个类处理业务逻辑的公共部分抽离出来,达到现复用、简化代码、解耦的目的。主要通过动态生成其代理对象来实现,常见的主流技术有JDK和CGLIB。

    spring的AOP是基于JDK和CGLIB两种动态代理技术作为支撑的,默认为JDK代理,可以收到配置强制使用CGLIB,如果代理类没有实现接口也会采用CGLIB进行代理,Spring AOP典型使用为事务、通知等,同时我们也可以用来做请求日志记录、鉴权等操作

    12、说下springmvc的流程

    分析:考察springmvc的理解,需要平时注意、积累经验

    答:

    • 用户发送请求至前端控制器DispatcherServlet
    • DispatcherServlet收到请求后,调用HandlerMapping处理器映射器,请求获取Handler
    • 处理器映射器根据请求url找到具体的处理器Handler,生成处理器对象及处理器拦截器(如果有则生成),一并返 回给
      DispatcherServlet;
    • DispatcherServlet 调用 HandlerAdapter处理器适配器(就是为了匹配参数),请求执行Handler;
    • HandlerAdapter 经过适配调用 具体处理器进行处理业务逻辑(controller);
    • Handler执行完成返回ModelAndView;
    • HandlerAdapter将Handler执行结果ModelAndView返回给DispatcherServlet;
    • DispatcherServlet将ModelAndView传给ViewResolver视图解析器进行解析;
    • ViewResolver解析后返回具体View;
    • DispatcherServlet对View进行渲染视图(即将模型数据填充至视图中)
    • DispatcherServlet响应用户

    在这里插入图片描述

    13、Spring如何保证线程安全的?

    分析:考察对spring整体理解,以及线程安全方面的综合知识,spring是没有解决线程安全的,可以从bean的作用域回答

    答:首先spring并未帮我们解决线程安全的问题,在spring中bean的作用域分别为 单例、多例、request、session级别、容器级别goal-session,其中只有多例是线程安全的,其他都会有线程安全问题,因此如果要解决安全问题,可以将bean设置成多例模式,另外基于bean的创建特性,我们的bean如果是无状态bean也不会有安全问题,因此我们在设置bean的时候尽量不要给bean动态赋值,保证bean为无状态bean,另外还可以给bean赋值或者操作值时加锁,不过性能比较低。

    14、Spring事务和Mysql事务有什么区别?

    分析:这种就是面试官挖坑,看你是否真正理解spring 事务本质

    答:spring是没有事务的事务是由数据库本身决定的,spring只是管理事务,如果数据库本身不支持,那spring也不会生效

    15、spring的事务失效场景

    分析:spring事务是基于aop实现的,所以让aop失效的都会导致事务失效,另外还和数据库本身有关

    :1.public方法 会导致事务失效,因为不能进行JDK或者CGLIB代理
    
    2.调用本类的方法 (调用this.methodC方法),通过this调用不会走代理类
    
    3.抛出捕捉的非RuntimeException,如果想要捕捉所有异常(rollbackFor = {Exception.class}) 
    或者指定@Transactional(rollbackFor = {RuntimeException.class,ClassNotFoundException.class},
    propagation = Propagation.REQUIRED) 多个异常类
    
    4.事务隔离级别设置成 不支持事务
    
    5.数据库不支持事务
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    16、说说你对spring事务的理解?

    分析:从事务的隔离级别、传播机制、spring事务三个方面作答

    答:首先spring是没有事务的,事务是由数据库本身决定的,spring的事务开启方式有两种,一个是声明式事务,一个是编程式事务,声明式事务是通过添加Transaction注解 的方式开启事务,使用spring aop实现,一般加在类或者方法上,事务控制粒度比较大,但使用上比较方便,编程式事务通过 TransactionTemplate,控制事务的粒度小,但是代码侵入性比较强。

    spring事务提供了7中传播机制:

    1. REQUIRED(必须的):是默认的传播机制,如果B方法中调用A,如果B中有事务,则A无论是否开启事务都会用B 的事务,
    任何地方出现异常AB都回滚
    
    2. REQUIRES_NEW(需要新的):每次都会开启一个新的事务,外面事务回滚,里面事务不会回滚
    
    3. SUPPORTS(1): 如果存在一个事务,支持当前事务。如果没有事务,则非事务的执行,完全依赖最外层事务
    
    4. MANDATORY(强制性的):必须运行在事务里面
    
    5. NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起
    
    6. NEVER:以非事务方式执行,如果当前存在事务,则抛出异常 7. NESTED:开启新事务,提交事务依赖于外层事务,
    如果外层事务回滚,则里面事务也回滚
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    spring事务还提供了四种隔离级别:

    1. DEFAULT(-1):数据库默认的隔离级别
    
    2. READ_UNCOMMITTED(1):读未提交 ru,会导致脏读
    
    3. READ_COMMITTED(2):读已提交 rc 避免脏读,允许不可重复读和幻读
    
    4. REPEATABLE_READ(4):可重复读 rr 避免脏读,不可重复读,允许幻读,innodb存储引擎解决了幻读
    
    5. SERIALIZABLE:串行化(不会使用这种)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
  • 相关阅读:
    【SpringBoot】68、SpringBoot解决HttpServletRequest中输入流不能重复读的问题
    系统架构设计师学习笔记——软件工程
    [Git] 系列三随意修改提交记录以及一些技巧
    xml笔记
    七天学会C语言-第四天(数组)
    搞数据库是不是越老越吃香?
    多尺度retinex图像去雾算法matlab仿真
    Python+Appium自动化搭建新手教程
    开发知识点-python-Tornado框架
    62.WEB渗透测试-信息收集- WAF、框架组件识别(2)
  • 原文地址:https://blog.csdn.net/qq_22075913/article/details/125833511