目录
前言
总结一些spring经典面试题
一、Bean创建的生命周期?
类对象 —> 构造方法(构造方法推断) —> 普通对象 —> 依赖注入 —> 初始化前(@PostConstruct
)—> 初始化(InitializingBean-》afterPropertiesSet()
)—> 初始化后(AOP)【创建代理对象,代理对象里面的bean对象指向前面创建的普通对象
】—> 放入Map(单例池)—> Bean对象
构造方法推断原理:
1.选择构造方法
最优先使用无参构造器
,只有单个有参构造器就使用这个有参构造器,有多个构造器时,有无参构造器就直接使用无参构造器,没有无参构造器直接报错,可以使用@Autowired注解指定使用某个构造器。
2.确定构造方法入参,先byType,再byName;根据类型匹配到唯一个对象直接使用,如有多个对象,再根据名字匹配匹配到唯一个对象即可使用否则报错。
Bean生命周期:
1.调用bean的构造方法创建Bean
2.通过反射调用setter方法进行属性的依赖注入
3.如果Bean实现了BeanNameAware接口,Spring将调用setBeanName(),设置 Bean的name(xml文件中bean标签的id)
4.如果Bean实现了BeanFactoryAware接口,Spring将调用setBeanFactory()把bean factory设置给Bean
5.如果Bean实现了ApplicationContextAware接口,Spring容器将调用setApplicationContext()给Bean设置ApplictionContext
6.如果存在BeanPostProcessor,Spring将调用它们的postProcessBeforeInitialization(预初始化)方法,在Bean初始化前对其进行处理
7.如果Bean实现了InitializingBean接口,Spring将调用它的afterPropertiesSet方法,然后调用xml定义的 init-method 方法,两个方法作用类似,都是在初始化 bean 的时候执行
8.如果存在BeanPostProcessor,Spring将调用它们的postProcessAfterInitialization(后初始化)方法,在Bean初始化后对其进行处理
9.Bean初始化完成,供应用使用,直到应用被销毁
10.如果Bean实现了DisposableBean接口,Spring将调用它的destory方法,然后调用在xml中定义的 destory-method方法,这两个方法作用类似,都是在Bean实例销毁前执行
二、Spring循环依赖
2.1 为什么会出现循环依赖?
多个bean之间相互依赖,形成了一个闭环。
实例化某一beanA时,beanA可能会依赖beanB(beanB又依赖beanA)依赖注入beanB,实例化beanB,又需要依赖注入beanA,此时beanA、beanB相互依赖都无法实例化。
2.2 如何去解决循环依赖?
Spring中单例Bean的三级缓存用来解决循环依赖问题。
2.3 一级缓存singletonObjects的作用是什么?
单例池,缓存经过完整bean生命周期的单例bean对象。
2.4 二级缓存earlySingletonObjects的作用是什么?
用来缓存出现循环依赖情况时,提前生成的没有经过完整bean生命周期的一些早期bean对象(属性还未填充完整)。【保证提前生成的代理对象的单例】
2.5 三级缓存singletonFactories的作用是什么?
存放可以生成Bean的工厂,用来打破循环依赖。