概述
一般只应用于单例模式,主要原理是将 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
也完成了整个生命周期