Spring常考面试题总结

Spring的IoC理解

IOC,Inversion of Control,控制反转(也叫:依赖注入),指将对象的控制权转移给Spring框架,由 Spring 来负责控制对象的生命周期(比如创建、销毁)和对象间的依赖关系。

最直观的表达就是,以前创建对象的时机和主动权都是由自己把控的,如果在一个对象中使用另外的对象,就必须主动通过new指令去创建依赖对象,使用完后还需要销毁(比如Connection等),对象始终会和其他接口或类耦合起来。而 IOC 则是由专门的容器来帮忙创建对象,将所有的类都在 Spring 容器中登记,当需要某个对象时,不再需要自己主动去 new 了,只需告诉 Spring 容器,然后 Spring 就会在系统运行到适当的时机,把你想要的对象主动给你。也就是说,对于某个具体的对象而言,以前是由自己控制它所引用对象的生命周期,而在IOC中,所有的对象都被 Spring 控制,控制对象生命周期的不再是引用它的对象,而是Spring 容器,由 Spring 容器帮我们创建、查找及注入依赖对象,而引用对象只是被动的接受依赖对象,所以这叫控制反转。

依赖注入

如上所述的一个例子,其实就是指的是 将调用者内部依赖的对象通过IOC容器注入调用者的过程。底层原理就是:反射

Spring的AOP理解

面向切面编程实际上是针对于OOP模式的一种补充,拿下面的一张图来解释即可:
在这里插入图片描述
面向切面,用于将那些与业务无关,但却对多个对象产生影响的公共行为和逻辑,抽取并封装为一个可重用的模块,这个模块被命名为“切面”(Aspect),减少系统中的重复代码,降低了模块间的耦合度,提高系统的可维护性。可用于权限认证、日志、事务处理。

实现方式通过代理来实现。具体见:静态代理与动态代理

spring 总览

在这里插入图片描述

BeanFactory 和 ApplicationContext 的区别?

https://zhuanlan.zhihu.com/p/115029344

BeanPostProcessor 和 BeanFactoryPostProcessor 的区别

BeanPostProcessor 具体实现:
在这里插入图片描述
BeanFactoryPostProcessor 具体实现:
在这里插入图片描述

总结区别

在这里插入图片描述

ApplicationContext 的实现

  1. FileSystemXmlApplicationContext :此容器从一个XML文件中加载beans的定义,XML Bean 配置文件的全路径名必须提供给它的构造函数。
  2. ClassPathXmlApplicationContext:此容器也从一个XML文件中加载beans的定义,这里,你需要正确设置classpath因为这个容器将在classpath里找bean配置。
  3. WebXmlApplicationContext:此容器加载一个XML文件,此文件定义了一个WEB应用的所有bean。

bean的生命周期

在这里插入图片描述

主要关键步骤

实例化 Instantiation --> 属性赋值 Populate --> 初始化 Initialization --> 销毁 Destruction

见:Spring常见面试题总结(超详细回答)

Spring 容器的启动流程?

  1. 初始化Spring容器,注册内置的BeanPostProcessor的BeanDefinition到容器中

① 实例化BeanFactory【DefaultListableBeanFactory】工厂,用于生成Bean对象
② 实例化BeanDefinitionReader注解配置读取器,用于对特定注解(如@Service、@Repository)的类进行读取转化成 BeanDefinition 对象,(BeanDefinition 是 Spring 中极其重要的一个概念,它存储了 bean 对象的所有特征信息,如是否单例,是否懒加载,factoryBeanName 等)
③ 实例化ClassPathBeanDefinitionScanner路径扫描器,用于对指定的包目录进行扫描查找 bean 对象

  1. 将配置类的BeanDefinition注册到容器中
  2. 调用 refresh() 方法刷新容器:

① prepareRefresh()刷新前的预处理:
② obtainFreshBeanFactory():获取在容器初始化时创建的BeanFactory:
③ prepareBeanFactory(beanFactory):BeanFactory的预处理工作,向容器中添加一些组件:
④ postProcessBeanFactory(beanFactory):子类重写该方法,可以实现在BeanFactory创建并预处理完成以后做进一步的设置
invokeBeanFactoryPostProcessors(beanFactory):在BeanFactory标准初始化之后执行BeanFactoryPostProcessor的方法,即BeanFactory的后置处理器
registerBeanPostProcessors(beanFactory):向容器中注册Bean的后置处理器BeanPostProcessor,它的主要作用是干预Spring初始化bean的流程,从而完成代理、自动注入、循环依赖等功能
⑦ initMessageSource():初始化MessageSource组件,主要用于做国际化功能,消息绑定与消息解析:
⑧ initApplicationEventMulticaster():初始化事件派发器,在注册监听器时会用到:
⑨ onRefresh():留给子容器、子类重写这个方法,在容器刷新的时候可以自定义逻辑
⑩ registerListeners():注册监听器:将容器中所有的ApplicationListener注册到事件派发器中,并派发之前步骤产生的事件:
⑪ finishBeanFactoryInitialization(beanFactory):初始化所有剩下的单实例bean,核心方法是preInstantiateSingletons(),会调用getBean()方法创建对象;
⑫ finishRefresh():发布 BeanFactory 容器刷新完成事件

如何解决循环依赖问题?

在这里插入图片描述

@Lazy 注解

与写时复制类似,主要解决构造方法造成的循环依赖问题

三级缓存

对于对象之间的普通引用,二级缓存会保存 new 出来的不完整对象,这样当单例池中找到不依赖的属性时,就可以先从二级缓存中获取到不完整对象,完成对象创建,在后续的依赖注入过程中,将单例池中对象的引用关系调整完成

三级缓存:如果引用的对象配置了AOP,那在单例池中最终就会需要注入动态代理对象,而不是原对象。而生成动态代理是要在对象初始化完成之后才开始的。于是Spring增加三级缓存, 保存所有对象的动态代理配置信息。在发现有循环依赖时,将这个对象的动态代理信息获取出来,提前进行AOP,生成动态代理。

核心代码就在 DefaultSingletonBeanRegistrygetSingleton 方法当中。

在这里插入图片描述

Spring 中什么时候 @Transactional 会失效?(有6种)

  1. 加了@Transactional 的方法只有是被代理对象调用时,那么这个注解才会生效,所以如果是原型对象来调用这个方法,那么@Transactional是不会失效的。举例:开发中避免不了会对同一个类里面的方法调用,比如有一个类Test,它的一个方法A,A再调用本类的方法B(不论方法B是用public还是private修饰),但方法A没有声明注解事务,而B方法有。则外部调用方法A之后,方法B的事务是不会起作用的。这也是经常犯错误的一个地方
  2. 同时如果某个方法是 private 的,那么@Transactional也会失效, 因为底层 cglib 是基于父子类来实现的,子类是不能重载父类的private方法的,所以无法很好的利用代理,也会导致@Transactianal失效
  3. 设置了相应的事务传播机制
  4. rollbackFor 设置错误,Spring默认抛出了未检查unchecked异常(继承自 RuntimeException 的异常)或者 Error才回滚事务;
  5. 异常被你的 catch“吃了”导致@Transactional 失效,如果是编译时异常不会自动回滚,如果是运行时异常,就会自动回滚!
  6. 数据库引擎不支持事务

Spring常见面试题总结(超详细回答)
史上最全的Spring面试题汇总
Spring面试题(2021最新版)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值