谈一谈你对IOC的理解
1、IOC即控制反转,是一种设计思想,有了spring后,我们将创建对象的权力交给spring,而不用自己去new一个对象。依赖注入就是IOC的一种具体实现,把对应的属性值注入到具体的对象中
@autowired 用populatebean()方法进行属性填充
2、容器:使用map结构来存储bean对象,在spring中存在三级缓存机制
整个bean的生命周期,从创建到使用到销毁都是由容器来管理。
谈一谈springIOC的底层实现
1、通过createbeanfactory创建出一个bean工厂
2、开始创建对象,因为容器中的bean默认都是单例的,所以会优先通过getbean、dogetbean去查找
如果找不到的话再去通过createbean、docreatebean方法去创建对象
一般都是利用反射的方式,使用无参构造创建对象
3、对创建的对象进行属性的填充
4、完成其他的初始化操作
Spring创建bean的流程
1、调用(createbeanfactory)DefaultListableBeanFactory方法,创建beanFactory工厂。
2、加载bean.xml文件,并封装成beandefinition。
3、调用执行beanfactorypostprocessor增强器对bean进行扩展。
4、初始化多播器和监听器,对bean的实例化做最后的准备工作。
5、利用反射(获取无参构造方法)实例化bean对象,此时的bean只是一个空对象。
6、bean的初始化过程(调用populateBean方法对bean进行属性的填充,
检查aware相关接口并设置相关依赖,调用beanpostprocessor前置处理,
调用init方法,最后调用beanpostprocessor后置处理)
7、至此完整的bean被创建,可以被使用,最后进行销毁。
什么是循环依赖?什么情况下循环依赖可以被处理?
循环依赖从字面上理解就是A依赖于B,B依赖于A,在创建bean对象的时候会形成一个闭环问题。
同时解决循环依赖是有前提条件的。1、bean是单例的 2、依赖注入的方式不能都是构造器注入
spring如何解决循环依赖?具体的流程?
spring通过三级缓存解决循环依赖。
当A、B发生循环依赖时,A会调用getbean()方法进行实例化,同时利用实例化后的这个空对象去创建一个早期暴露对象工厂,并放入三级缓存中,当A进行属性注入时,也会调用getbean()方法去实例化一个B对象,同时B又依赖了A,所以又会调用getbean(a)方法去获取所需的依赖,但是这次的getbean和之前的getbean不同,此时我们会去三级缓存中获取对象,调用getObject()方法获得一个早期暴露对象,得到这个对象后将其注入到B中,紧接着对B进行初始化以及执行后置处理器。当B创建完毕后,将B再注入到A中,完成A的初始化工作。至此,循环依赖结束。
三级缓存存储的都是什么东西?
一级缓存:完整的bean对象
二级缓存:只完成实例化的bean,未进行初始化、属性赋值,简称为早期曝光对象
三级缓存:生产早期暴露对象的工厂
spring只用一级缓存可以吗?只用二级可以吗?为什么要用三级?
1、
不可以,只用一级缓存的话,完整的bean对象和不完整的bean对象都放在一起,在对象的获取时,可能会获取到不完整的bean。
2、
只用二级缓存可以解决循环依赖的问题,但是在添加AOP实现后,会报错。
因为AOP实现的是代理模式,而三级缓存的核心逻辑就是利用代理对象去替换非代理对象,
如果不加三级缓存就得不到代理的对象。
3、
三级缓存的核心逻辑在getEarlyBeanReference()方法里体现
在当前方法中,可能会用代理对象去替换非代理对象,如果没有三级缓存的话,将无法获得代理的对象
因此添加三级缓存的作用就是用代理对象去替换非代理对象,从而确定返回的是一个唯一的对象。
BeanFactory和FactoryBean有什么区别
相同点:都是用来创建bean对象的
不同点:使用beanfactory来创建对象的时候需要严格遵循生命周期流程,比较复杂。
如果想要某个简单的自定义对象,同时创建完成的对象想交给spring管理,那么就可以实现factorybean接口。
Spring用到的设计模式
单例模式:bean默认都是单例的
原型模式:指定作用域为prototype
工厂模式:beanfactory
模板方法模式:postporcessbeanfactory,onRefresh
观察者模式:创建bean时用到的多播器和监听器
策略模式:xmlbeandefinitionReader
适配器模式:adapter
装饰着模式:BeanWrapper
责任链模式:使用AOP的时候会先生成一个拦截器链
代理模式:动态代理
Spring的AOP的底层实现原理
aop即面向切面编程,是bean创建流程的一个扩展功能, 主要实现方法 beanpostprocessor。
1、代理对象的创建
2、通过jdk或者cglib的方式生成代理对象
3、再执行方法调用的时候,会调用到生成的字节码文件,直接回调到intercept方法。
4、根据之前定义好的通知来生成拦截器链
5、从拦截器链中依次获取每一个通知进行执行,在执行过程中,为了方便找到下一个通知是哪个
会有一个invocationInterceptor对象,从-1的位置依次开始查找并执行。
Spring的事务是如何回滚的
1.先做准备工作,解析各个方法上事务相关的属性,根据具体的属性来判断是否开启新事务。
2.当需要开启的时候,获取数据库连接,关闭自动提交功能,开启事务。
3.执行具体的sql逻辑操作
4.在操作的过程中,如果执行失败了,那么会通过completeTransactionAfterThrowing来完成事务的回滚操作,回滚具体的逻辑是通过doRollBack方法来实现的,实现的时候也是先获取连接对象,通过连接对象来回滚。 5.如果执行过程中,没有发生任何异常,那么会通过commitTransactionAfterReturning来完成事务的提交操作,提交的具体逻辑是通过doCommit方法来实现的,实现的时候也是先获取连接对象,通过连接对象提交。
6.当事务执行完毕之后需要清除相关的事务信息cleanupTransactionInfo