本文主要内容:分析 Spring 加载 bean 的过程,重点分析下 Spring 解决循环依赖的三级缓存。
refresh方法
IoC 初始化过程中核心方法 refresh :
org.springframework.context.support.AbstractApplicationContext#refresh :
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
// 刷新上下文
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
// 在子类中启动 refreshBeanFactory。 该方法执行完成之后,xml中的bean已经加载完成,但是 注解方式的bean 在
// invokeBeanFactoryPostProcessors 加载
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
// 设置BeanFactory的后置处理
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
// 调用BeanFactory的后处理器,这些后处理器是在Bean定义中项容器注册的,这里面会实例化 后置处理器的bean对象
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
// 注册Bean的后处理器,在Bean创建过程中调用
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
// 对上下文中的消息源进行初始化
initMessageSource();
// Initialize event multicaster for this context.
// 初始化上下文中的事件机制
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
// 初始化其他特殊Bean
onRefresh();
// Check for listener beans and register them.
// 检查监听Bean并且将这些Bean向容器注册
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
// 实例化所有的单例bean
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
// 发布容器事件,结束Refresh过程。
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// Destroy already created singletons to avoid dangling resources.
// 为防止Bean资源占用,在异常处理中,销毁已经在前面过程中生成的单例bean
destroyBeans();
// Reset 'active' flag.
// 重置 active 标志
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
}
}
}
bean 加载过程分析
xml 方式(ClassPathXmlApplicationContext) 和 注解方式(AnnotationConfigApplicationContext) 启动 Spring 容器,bean 加载过程处理方式不太一样
xml 方式
xml 方式加载过程主要是 obtainFreshBeanFactory 这个方法,先通过文件流读取 xml 文件中的信息,loadBeanDefinitions 方法解析 xml 文件,将其中的内容加载成 beanDefinition,放到 beanDefinitionMap 中,通过 BeanFactory.getBean 方法生产bean
注解方式
注解方式加载过程主要是 invokeBeanFactoryPostProcessors 这个方法,AnnotationConfigApplicationContext 在 new AnnotatedBeanDefinitionReader 的时候会注册一些 bean 后置处理器
- ConfigurationClassPostProcessor
- AutowiredAnnotationBeanPostProcessor
- CommonAnnotationBeanPostProcessor
通过 BeanFactory.getBean 方法生产bean
BeanFactory.getBean
BeanFactory 中最重要的方法就是 getBean,这个方法既可以获取 bean、也可以生产 bean,获取 bean 是从缓存中去拿,如果缓存中没有在去生产 bean 。
三级缓存解决循环依赖
假设这么一个场景
class A{
@Autowired
private B b;
}
class B{
@Autowired
private A a;
}
A 依赖 B,B 又依赖 A,但是 Spring 却没有出现 循环依赖,其解决方式是通过 三个缓存 map 。
一级缓存,存的是实例化、初始化完成的 bean,最终的 bean,可以直接拿来用的
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
二级缓存,存放的是完成实例化,但是还未进行初始化的 bean
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);
三级缓存,进入实例化阶段的单例 bean
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
通过一个流程图来看下 A、B 两个类在 IOC 加载创建 bean 的流程,注意,图中省略了好多步骤、细节部分,但是不影响主流程。
竖向表示当前方法的执行顺序,横向表示进入到该方法。
这个流程图分为了 三列,第一列创建 bean A 的流程,在创建 A 的时候发现要依赖 B,第二列就是创建 bena B 的流程,在创建 B 的时候又发现依赖 A,第三列就是 创建 B 的时候 创建 A 的流程。
图中用颜色标注的是表示用到三级缓存的地方。
- 第一个是在获取缓存的方法 getSingleton 中,先从第一级缓存去查找,如果没有则去第二级缓存中查找,没有再去第三级缓存中查找,如果第三级缓存中查到了,将其从第三级缓存中删掉,放到第二级缓存中。
- 第二个用到缓存的地方是 doCreateBean 中,bean 通过反射获取到实例后,先放入到第三级缓存中
- 第三个是 doCreateBean 完成后,bean 都初始化好,放入到第一级缓存中
创建 A 的时候发现要依赖 B,于是递归调用 getBean(B) 去创建 B,这个时候三个缓存中只有第三级缓存中有 A
创建 B 的时候发现要依赖 A,于是递归调用 getBean(A)去创建 A ,这个时候第三级缓存中有 A、B,于是从第三级缓存中取出 bean A,放到二级缓存中去,接着执行创建 B 的流程,B 初始化完成后,将 B 放到第一级缓存
然后在执行创建 A 的流程,初始化实例 A,完事后将 A 也加入到第一级缓存中。
每个步骤对应的三个缓存中的内容:
以上;