Spring八股文
Bean的生命周期
1.通过反射生成对象
2.填充Bean的属性
3.调用aware接口的invokeAwareMethod方法,对BeanName、BeanFactory、BeanClassLoader对象的属性设值
4.调用BeanPostProcessor的前置处理方法,其中使用较多的是ApplicationContextPostProcessor,设置ApplicationContext、Environment、ResourceLoader、EmbeddValueResolver等对象
5.调用initmethod方法,invokeInitmethod(),判断是否实现了initializingBean接口,如果有,则调用afterPropertiesSet方法,没有就不调用
6.调用BeanPostProcessor的后置处理方法,Spring的AOP就是在这里实现的
7.通过getBean获取完整的对象
8.进入销毁流程,判断是否实现了DispoableBean接口,然后调用destroyMethod方法
Spring是如何解决循环依赖问题的
三级缓存、提前暴露对象、aop
所有的Bean对象在创建的时候首先放进三级缓存中,在后续的使用过程中,如果需要被代理则返回代理对象,如果不需要被代理,则直接返回普通对象。
缓存的放置时间和删除时间
三级缓存:createBeanInstance之后
二级缓存:第一次从三级缓存中确定对象是代理对象还是普通对象,之后删除三级缓存
一级缓存:生成完整对象之后放到一级缓存,删除二三级缓存
Bean Factory和FactoryBean有什么区别
相同点:都是用来创建Bean对象的
不同点:如果使用BeanFactory创建对象,必须遵守spring的生命周期,此过程很复杂。如果只是想简单的创建一个Bean,同时交于Spring进行管理,可使用FactoryBean来创建
isSingleton:是否是单例对象
getObjectType:获取返回对象的类型
getObject:自定义创建对象的过程(new,反射,动态代理)
Spring中用到哪些设计模式?
1.工厂模式:BeanFactory就是工厂模式
2.单例模式:Bean默认都是单例的
3.模板方法:postProcessBeanFactory、onRefresh、initPropertyValue
4.原型模式:指定作用域为prototype
5.策略模式:XmlBeanDefinitionReader、PropertiesBeanDefinitionReader
6.观察者模式:listener、event、multicast
7.适配器模式:Adapter
8.装饰者模式:BeanWrapper
9.责任链模式:使用aop的时候,会先生成一个拦截器链
10.代理模式:动态代理
11.委托者模式:delegate
…
SpringAOP的底层实现原理
动态代理
先有IOC,后有AOP,AOP是对Bean的扩展实现,所以在BeanPostProcessor后置处理方法中来实现的。
1.代理对象的创建过程(advice、切面、切点)
2.通过jdk或者cglib的方式来生成代理对象
3.在执行方法调用的时候,会调用到生成的字节码文件中,直接会找到DynamicAdvisoredlnterceptor类中的intercept方法,从此方法开始执行
4.根据之前定义好的通知来生成拦截器链
5.从拦截器链中依次获取每一个通知开始进行执行
Spring的事务是如何回滚的
spring的事务是由aop来实现的,首先要生成具体的代理对象,然后按照aop的执行流程来执行具体的操作逻辑,正常情况下要通过通知来完成核心功能,但事务不是通过通知来实现的,而是通过TransactionInterceptor来实现的,调用invoke来实现具体的逻辑。
1.先做准备工作,解析各个方法上事务相关属性,根据具体的属性判断是否开启新事务
2.当需要开启的时候,获取数据库链接,关闭自动提交功能,开启事务
3.执行具体的sql逻辑操作
4.在操作过程中,如果执行失败了,会通过completeTransactionAfterThrowing来完成事务的回滚操作,回滚的具体逻辑是通过doRollBack方法来实现的,实现的时候也是要先获取链接对象,通过链接对象来回滚
5.如果执行过程中,没有任何意外情况的发生,那么通过commitTransactionAfterReturning来完成事务的提交操作,提交的具体逻辑是通过doCommit方法来实现的,实现的时候也是要获取链接,通过链接对象来提交
6.当事务执行完毕之后需要清除相关的事务信息,cleanupTransactionInfo
spring事务传播特性
spring的事务传播特性有7种
1.Required
2.Requires_new
3.nested
4.Support
5.Not_Support
6.Never
7.Mandatory
某一个事务嵌套另一个事务的时候怎么办?(A方法调用B方法,AB方法都有事务,但是传播性不同,那么A如果有异常,B怎么办?B如果有异常,A怎么办?)
事务的传播特性指的是不同方法的嵌套调用过程中,事务应该如何进行处理,是用同一个事务还是不同的事务,当出现异常的时候是回滚还是提交,两个方法之间相关影响,在日常工作中,使用较多的是required、Requires_new、nested
事务可以分为三类:支持当前事务、不支持当前事务、嵌套事务
核心处理逻辑:
1.判断内外方法是否为同一个事务
是:异常统一在外层方法处理
不是:内层方法有可能影响到外层方法,但是外层方法是不会影响到内层方法的
SpringIOC的底层实现
反射、工厂、设计模式
1.先通过createBeanFactory创建Bean工厂
2.循环创建Bean对象,因为容器都是单例的,所以优先通过getBean、doGetBan从容器中查找,找不到的话
3.通过createBean、doCreateBean方法,通过反射的方式创建对象,一般情况下使用的是无参的构造方法
4.进行对象额属性填充populateBean
5.进行其他初始化操作(initializingBean)
ApplicationContext和BeanFactory有什么区别?
1.BeanFactory创建bean采用延迟加载形式,也就是说你需要getBean()才会加载
2.ApplicationContext创建Bean默认采用立即加载,ApplicationContext继承了BeanFactory
如何控制Bean的加载顺序?
使用@DependsOn即可控制Bean的加载顺序
- 配置在方法上,将优先于@Bean配置的bean进行加载
- 配置在类上,将优先于当前类中所有@Bean配置的Bean进行加载
- 配置在类上,将优先于@Compent等配置的Bean进行加载
- 相关属性:value(默认),设置当前bean所依赖的bean的id