高频面试Spring之IOC

1、简介

IOC的目的:控制反转和依赖注入

2、IOC过程简析(针对单例Bean)

该问题考察是否读过Spring IOC 源码,以下列举部分流程,应对面试是没问题的:

  • 解析配置文件、或注解元数据,将bean的定义转换为BeanDefinition
  • 调用getBean()方法获取bean。首先查找缓存,若存在,返回;否则,做创建bean的准备工作,合并BeanDefinition、实例化依赖bean
  • 调用doCreateBean方法,创建bean的实例
    • 通过createBeanInstance方法并根据实例化策略(Supplier、工厂方法、静态工厂方法、构造函数)例化当前bean
    • 如果存在方法注入(replace_method、lookup_method),使用CGLib创建实例;否则使用反射
    • 到这一步,对象已经被创建,相当于完成了控制反转
  • 调用populateBean方法填充bean的属性,即依赖注入
    • 解析自动装配类型,by_name、by_type
    • 调用applyPropertyValue应用bean的属性
    • 至此,依赖注入的工作也完成了
  • 调用生命周期相关的接口,依次为(注意顺序)
    • BeanNameAware 修改bean名称
    • BeanFactoryAware、ApplicationContextAware 可将两者实例暴露出来,方便在其它地方获取bean的实例
    • PostConstruct、InitializingBean、init_method
    • DisposableBean、destroy-method
3、常见问题
3.1 三级缓存

第一级缓存:单例 singletonObjects = new ConcurrentHashMap<>(256);
第二级缓存:早期提前暴露的对象缓存 earlySingletonObjects。(属性还没有值对象也没有被初始化
第三级缓存:singletonFactories单例对象工厂缓存

3.1 循环依赖

只能解决setter方法注入的、单例的循环依赖。通过缓存正在创建Bean实例的方式来解决循环依赖。理解循环依赖问题的关键是理解IOC的过程,反射创建对象实例后,并不能立即被使用,后续还有依赖注入、生命周期接口调用等操作。所以可以提前缓存(曝光)该bean的实例。

3.2 BeanFactory和FactoryBean

理论上讲两者之间没有什么可比性,但是比较常问。

  • BeanFactory接口:IoC顶级接口,定义了bean的创建,访问等工作
  • FactoryBean接口:工厂bean,该接口可以对bean进行一些额外的操作,如创建不同类型的bean、简化xml配置等。获取BeanFactory类型的bean时,如果beanName不加&则获取到对应bean的实例;如果beanName加上&,则获取到BeanFactory本身的实例

你可能感兴趣的:(高频面试题,spring,面试,java)