Spring源码分析(基于秋招)

Spring源码分析(基于秋招)(系列文章基于Spring5.0)

整体源码分析是为了面试的时候给面试加分的,大佬勿喷!!!

1.谈谈你对Spring IOC的理解

IOC:控制翻转,原来我是用的时候是由使用者控制的,有了Spring之后,可以将整个对象交给容器来帮我们进行管理(理论思想)

DI:依赖注入,将对应的属性注入到具体的对象中,@Autowired,@Resource,populateBean方法来完成属性的注入

@Autowired,@Resource的区别:

在这里插入图片描述

容器:存储对象,使用map结构存储对象,在spring中存储对象的时候一般有三级缓存,singletonObjects存放完整的对象,earlySingletonObjects存放半成品对象,singletonFactory用来存放lambda表达式和对象名称的映射,整个bean的生命周期,从创建到使用到销毁,各个环节都是容器来帮我们控制的

bean的生命周期:

循环依赖问题是怎么产生的?

当然,在整个IOC体系中还有很多细节上的点,但是我是之前看的,太久了,记不清楚了,Spring中整个bean都是通过反射生成的 ,constructor,newlnstance,在整个流程中还包含了很多可扩展点,比如有两个非常重要的接口BeanFactoryPostProcessor,BeanPostProcessor,用来实现扩展的功能,aop就是在ioc基础上的一个扩展实现,是通过BeanPostProcessor用来实现扩展功能,IOC中除了创建对象之后还有一个重点的点就是填充属性,生命周期的东西能说多少说多少

2.简单描述bean的生命周期

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1l9DVoOE-1635407315397)(https://www.javazhiyin.com/wp-content/uploads/2019/05/java0-1558500658.jpg)]

spring容器帮助我们去管理对象,从对象的产生到销毁环节都是有容器来控制的,其中主要包括实例化和初始化两个关键环节,当然在整个过程中会有一些扩展点的存在,下面来详细描述下各个环节和步骤:

  1. 实例化bean对象,通过反射的方式来生成,在源码中有一个createBeanInstance的方法时专门用来生成对象的
  2. 当bean对象创建之后,对象的属性值,都是默认值,所以要开始给bean填充属性,通过populateBean来完成对象属性的填充,中间会涉及到循环依赖的问题,后面详说
  3. 向bean对象中设置容器属性,会调用invokeAwareMethods方法来将容器对象设置到具体的bean对象中
  4. 调用BeanPostProcessorProcessor中的前置处理方法来处理bean对象的扩展工作,ApplicationContextPostProcessor,EmbeddValueResolve等对象
  5. 调用invokeInitMethods方法来完成初始化方法的调用,再次方法处理过程中,需要判断当前bean对象是否实现了InitalizingBean接口,如果实现了调用afterPropertiesSet方法来最后设置bean对象
  6. 调用BeanPostProcessor的后置处理方法,完成对bean对象的后置处理工作,aop就是在此处实现的,实现的接口名字叫做AbstractAutoProxyCreator
  7. 获取到完整对象,通过getBean的方式去进行对象的获取和使用
  8. 当对象使用完成之后,容器在关闭的时候,会销毁对象,首先会判断是否实现了DispoableBean接口,然后去调用destoryMethod方法

3.BeanFactory和FactoryBean的区别

BeanFactory和FactoryBean都可以用来创建对象,只不过创建的流程和方式不同

当使用BeanFactory的时候,必须要严格遵守bean的生命周期,经过一系列繁杂的步骤之后次啊可以创建出单例对象,是流水线式的创建过程

而FactoryBean是用户可以自定义bean对象的创建流程,不需要按照bean的生命周期来创建,在此接口包含了三个方法,

isSingleton:判断是否是到单例对象

getObjectType:获取对象的类型

getObject:在此方法中可以自己创建对象,使用new方式或者使用代理的方法都可以,用户可以按照自己的需要随意去创建对阿香,很多框架继承的时候都会实现FactoryBean接口,比如Feign

4.spring中用到哪些设计模式

单例模式:spring中bean都是单例模式

工厂模式:BeanFactory

模板方法:PostProcessorBeanFactory,onRefresh

观察者模式:listener,event,multicast

适配器模式:Adapter

代理模式:aop动态dialing

策略模式:XmlBeanDefinitionReader,PropertiesBeanDefinitionReader

5.BeanFactory和ApplicationContext的区别

BeanFactory是访问Spring容器的跟接口,里面只是提供了某些方法的约束和规范,为了满足更多的需求,Application实现了此接口,并在此接口的基础上做了某些扩展功能,提供了更加丰富的api调用,一般我们在使用的时候用applicationContext更多

6.谈谈你对循环依赖的理解

spring中bean对象的创建都要经历实例化和初始化(属性填充)的过程,通过将对象的状态分开,存在半成品和成品对象的方式,来分别进行初始化和实例化,成品和半成品在存储的时候需要分不同的缓存来进行存储

  1. 只有一级缓存行不行?

不行,会把成品状态的bean对象和半成品很脏太的bean对象放到一起,而半成品对象是无法暴露给外部使用的,所以要将成品和半成品分开,一级缓存中存放成品对象,二级缓存半成品对象

  1. 只有二级缓存行不行?

如果整个应用程序不涉及aop的存在,那么二级缓存足以解决循环依赖的问题,如果aop中存在了缓存依赖,那么就必须要要使用三级缓存才可以解决

  1. 为什么需要三级缓存?

三级缓存的value类型是ObjectFactory是一个函数式接口,不是直接调用的,只有在调用getObject方法才回去调用里面存储的lamba表达式,存在的意义保证在整个容器的运行过程中同名的bean对象只能有一个

如果有一个对象要被代理,或者需要生成代理,那么要不要先生成一个原始对象?要

当创建出代理对象之后,会同时存在代理对象和普通对象,那么此时我改用哪一个?代理对象

程序是死的,他怎么知道先用谁?后用谁?

所以当需要代理对象的时候,或者代理对象生成的时候必须要覆盖原始对象,也就是说 整个容器中有且只有一个bean对象

在实际调用的过程中,是没有办法来确定什么时候对象需要被调用,因此当某一个对象要被调用的时候,优先判断当前对象是否需要被代理,类似于回调机制,当获取对象之后根据传入的lamba表达式来确定返回的是哪一个确定的对象,如果条件符合,返回代理对象,如果不符合,返回原始对象

7.Spring的AOP的底层原理

动态代理

aop是ioc的扩展功能,现有的IOC,后有的aop,只是在ioc新增的一个扩展点而已:BeanPostProcessor

总:aop概念,应用场景,动态代理

分:bean的创建过程中有一个步骤可以对bean进行扩展实现,aop本身就是一个扩展功能,所以在BeanPostProcessor的购置处理方法来进行实现:

  1. 代理对象的创建过程(advice,切面,切点)
  2. 通过jdk或者cglib的方式来生成代理对象
  3. 在执行方法调用的时候,会调用到生成的字节码文件汇总,直接找回到DynamicAdvisoredlnterceptor类中的intercept方法,从此方法执行
  4. 根据之前定义好的通知来生成拦截器链
  5. 从拦截器链中以此获取到每一个通知开始进行执行,在执行过程中,为了方便找到下一个通知是哪个,会有一个CglibMethodinvocation的对象,找的时候是从-1位置一次开始查找并且执行的

8.Spring的事务是如何回滚的?

spring的事务管理是如何实现的?

总:spring的事务是由aop实现的,首先要生成具体的代理对象,然后按照aop的整套流程来执行具体的操作逻辑,正常情况下通过通知来完成核心功能,但是事务不是通过通知来实现的,而是通过Transactioninterceptor来实现的,然后调用invoke来实现具体的逻辑

分:1. 先做准备工作,解析各个方法上事务相关的属性,感觉具体的属性来判断是否开启新事物

  1. 当需要开启的时候,获取数据库连接,关闭自动提交功能,开启事务
  2. 执行具体的SQL逻辑操作
  3. 在操作过程中,如果执行失败了,那么会通过completeTransactionAfterThrowing看来事物的回滚操作,具体的逻辑通过doRollBack方法里实现的,实现的时候也是要获取连接,通过连接对象回滚
  4. 如果执行过程中没有任何以外的发生,那么通过comomitTransactionAfterReturning来完成事物额提交操作,提交的具体逻辑是通过doCommit方法来实现的,实现的时候要也要获取连接,通过连接对象来提交
  5. 当事物执行完毕之后需要清楚相关的事物信息cleanTransactioninfo

9.谈一下spring事物传播?

传播特性:7种

Required、Requires_new、nested、Support、Not_Support、Never、Mandatory

某一个事物嵌套另一个事物的时候怎么办?

A方法调用B方法,AB方法都有事物,并且传播特性不同,那么A如果有异常,B怎么办,B如果有异常,A怎么办?

总:事物的传播特性指的是不同方法的嵌套调用过程中,事物应该如何处理,是用同一个事物还是不同的事物,当出现异常的时候会回滚还是提交,两个方法之间的相关影响,在日常工作中,使用比较多的是required,Requires_new,nested

分:1. 先说事物的不同分类:可以分为三类:支持当前事物、不支持当前事物、嵌套事物

  1. 如果外层方法是required、内层方法是:required、requires_new,nested
  2. 如果外层方法时required_new,内层方法是:required、requires_new,nested
  3. 如果外层方式nested,内层方式是:required、requires_new,nested
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值