Spring Bean实例化过程

上篇《Spring类扫描器记录》中, 记录了Spring扫描Class, 封装成一个个BeanDefinition的过程, ApplicationContext后续将根据这些Bean定义来建立Bean实例, BeanDefinition和Bean实例保存在的位置以下:

BeanDefinition保存到的实例变量(DefaultListableBeanFactory):

/** List of bean definition names, in registration order */
List<String> beanDefinitionNames

/** Map from bean name to merged RootBeanDefinition */
Map<String, RootBeanDefinition> mergedBeanDefinitions

Bean实例保存到的成员变量(DefaultListableBeanFactory):

/** 保存单例对象: bean名 --> bean实例 */
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(256);

一个[BeanDefinition]到一个[Bean实例]是经过BeanFactory#getBean方法完成的:

BeanFactory#getBean方法执行过程:

Tags:(BeanFactory具体对应的子类是DefaultListableBeanFactory)segmentfault

  1. 从单例缓存singletonObjects查找, 有则直接返回

没有则缓存

  1. 建立实例
  2. 执行bean后置处理器,调用Bean初始化方法
    依赖注入是后置处理完成的,也是调用BeanFactory#getBean获取依赖对象
  3. 保存实例到singletonObjects中

参考百度脑图: [调用beanFactory.getBean获取/建立实例]节点3d

问题记录

1. 实例化Bean的位置

在上下文刷新时AbstractApplicationContext#refreshcode

// 执行彻底部的BeanFactory后置处理
// ConfigurationClassPostProcessor会加载工程下的class到BeanDefinition
// 注册Bean后置处理器

// 根据BeanDefinition实例化全部单例Bean.
finishBeanFactoryInitialization(beanFactory);

2. 对象循环引用问题

getBean方法经过Bean后置处理器AutowiredAnnotationBeanPostProcessor注入依赖, 该后置处理器又将调用getBean获取依赖Bean, 例若有以下代码:对象

@Service
public class ServiceA {
    @Autowired
    ServiceB serviceB;
}

@Service
public class ServiceB {
    @Autowired
    ServiceA serviceA;
}

BeanFactory会将建立中的bean名保存到singletonsCurrentlyInCreation, 建立中的bean实例保存到singletonFactories。token

getBean("serviceA")的过程:

  1. 建立ServiceA实例
  2. 建立ServiceB实例
  3. 实例ServiceA注入到ServiceB (实例ServiceA仍在初始化中)
  4. ServiceB完成建立
  5. 实例ServiceB注入到ServiceA
  6. ServiceA完成建立

被依赖的Bean会先完成初始化
参考图片连接: Spring循环引用逻辑结构图图片

3. 单例Bean建立后注册到哪了?

DefaultSingletonBeanRegistry对象的singletonObjects字段, 这里注册的都是依赖已经注入, 且执行完Bean后置处理器的实例ip

/** Cache of singleton objects: bean name --> bean instance */
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(256);

4. 对象循环依赖异常

BeanCreationException: Circular depends-on relationship between
循环依赖会致使该异常, 如使用@DependsOn注解配置了依赖:get

@Service
@DependsOn("permission")
public class Role {
    @Autowired
    private Permission permission;
}


@Service
@DependsOn("role")
public class Permission {
    @Autowired
    private Role role;
}

Permission,Role互相依赖, 谁没法被建立, BeanFactory将抛出异常
BeanCreationException:
Circular depends-on relationship between 'role' and 'permission'it

相关文章
相关标签/搜索