概述
一般只应用于单例模式,主要原理是将 bean 先缓存在 beanfactory,prototype无法解决循环依赖问题。 示例代码
1 |
|
getBean(A)->instance(A)->autowired(B)->getBean(B)->instance(B)->autowired(A)->循环依赖
解决方案: 1.A首先调用构造函数newInstance,此时A的引用值已确定
- 将
A的引用缓存,创建B时直接使用缓存的A的引用
则实际实例化过程大致如下:
getBean(A)->instance(A)->cache reference(A)->autowired(B)->getBean(B)->instance(B)->autowired(A)->get reference(A)->postConstruct(B)->postConstruct(A)
源码分析
以AnnotationConfigApplicationContext的加载来举例
AppConfig为配置类,不重要
1 | AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class); |
省略其他过程直接看刷新
1 | public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) { |
省略扫描过程,直接看 bean 加载的过程
1 |
|
1 | protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) { |
DefaultListableBeanFactory类preInstantiateSingletons代码片段
1 | for (String beanName : beanNames) { |
通过getBean方法可以追踪到org.springframework.beans.factory.support.AbstractBeanFactory#getBean(java.lang.String),然后 org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean
1 | protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType, |
DefaultSingletonBeanRegistry
1 | private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256); |
首次创建A时,singletonObject肯定为null,isSingletonCurrentlyInCreation的代码很简单
1 | public boolean isSingletonCurrentlyInCreation(String beanName) { |
我们只需要了解singletonsCurrentlyInCreation是何时被add,通过查看调用关系,最终可以发现org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean中
1 | if (mbd.isSingleton()) { |
继续回到A的创建,在getSingleton中未取到缓存是,A尝试createBean,也就是上述代码部分。 追踪调用关系可以知道最终调用org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean(java.lang.String, org.springframework.beans.factory.support.RootBeanDefinition, java.lang.Object[])后进入org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean
节选片段
1 | protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) |
我们查看下addSingletonFactory的细节
1 | protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) { |
到这里bean通过构造器创建实例的过程结束了,但是bean在spring容器中的生命周期还未结束,后续发现A依赖B,则会去创建B,B在实例化后加载依赖时,会去创建A,不同的是在调用DefaultSingletonBeanRegistry的getSingleton时判断条件isSingletonCurrentlyInCreation时A已在创建过程中,那么就会去执行
1 | protected Object getSingleton(String beanName, boolean allowEarlyReference) { |
此时B顺利完成整个Spring生命周期,从而A也完成了整个生命周期