1. 编写测试代码
为演示循环依赖的效果,咱来编写两个组件,模拟人与猫的关系:人养猫,猫依赖人。
复制 @ Component
public class Person {
@ Autowired
Cat cat;
}
@ Component
public class Cat {
@ Autowired
Person person;
}
之后使用包扫描来启动IOC容器:
复制 public class App {
public static void main ( String [] args) throws Exception {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext( "com.example.demo.component" ) ;
String [] beanDefinitionNames = ctx . getBeanDefinitionNames ();
Stream . of (beanDefinitionNames) . forEach ( System . out :: println);
}
}
运行,发现可以正常打印cat和dog:
复制 org.springframework.context. annotation .internalConfigurationAnnotationProcessor
org.springframework.context. annotation .internalAutowiredAnnotationProcessor
org.springframework.context. annotation .internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
person
cat
下面来结合上一篇中的bean创建流程,分析IOC容器是如何解决循环依赖的。
【下面的源码不再使用通篇+描述,而是使用步骤来一步步描述过程,小伙伴要跟上思路来一起分析】
2. 流程全分析 - 初始化IOC容器
2.1 new AnnotationConfigApplicationContext
复制 public AnnotationConfigApplicationContext( String ... basePackages ) {
this ();
scan(basePackages) ;
refresh() ;
}
前面的创建和包扫描部分,会把Cat和Dog都读进 BeanFactory
。
下面的refresh方法:
2.2 refresh
复制 public void refresh() throws BeansException , IllegalStateException {
synchronized ( this . startupShutdownMonitor ) {
// ......
try {
// ......
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory) ;
// ...
}
// ......
}
}
最终会调用到11步:初始化剩余的单实例Bean 。
2.3 finishBeanFactoryInitialization
复制 protected void finishBeanFactoryInitialization( ConfigurableListableBeanFactory beanFactory) {
// ...
// Instantiate all remaining (non-lazy-init) singletons.
beanFactory . preInstantiateSingletons ();
}
直接走到最后一步:preInstantiateSingletons
:
2.4 DefaultListableBeanFactory#preInstantiateSingletons
复制 public void preInstantiateSingletons() throws BeansException {
// ......
// Trigger initialization of all non-lazy singleton beans...
for ( String beanName : beanNames) {
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName) ;
if ( ! bd . isAbstract () && bd . isSingleton () && ! bd . isLazyInit ()) {
if ( isFactoryBean(beanName) ) {
// ......
}
else {
getBean(beanName) ;
}
}
}
// Trigger post-initialization callback for all applicable beans...
// ......
}
到此为止,开始进行真正的Bean创建。
Debug中可以看到,由于Cat在Person之前,所以先来创建Cat:
3. 流程全分析 - 初始化Cat
由上面的 getBean
,跳转到 AbstractBeanFactory
的 getBean
方法:
复制 public Object getBean( String name) throws BeansException {
return doGetBean(name , null , null , false ) ;
}
紧接着调 doGetBean
:
3.1 doGetBean(cat)
复制 protected < T > T doGetBean( final String name , @ Nullable final Class< T > requiredType ,
@ Nullable final Object [] args , boolean typeCheckOnly) throws BeansException {
// ......
// Create bean instance.
if ( mbd . isSingleton ()) {
sharedInstance = getSingleton(beanName , () -> {
try {
return createBean(beanName , mbd , args);
}
catch ( BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
destroySingleton(beanName);
throw ex;
}
}) ;
bean = getObjectForBeanInstance(sharedInstance , name , beanName , mbd) ;
}
// ......
return (T) bean;
}
在Lambda表达式中要调用 createBean
,但在调用之前先看一眼 getSingleton
方法:
3.2 【重要】getSingleton
这个方法来自 **DefaultSingletonBeanRegistry**
,这个类中有几个很重要的概念,就是它的几个成员(这几个成员都有文档注释):
**singletonObjects**
:一级缓存,存放完全初始化好的Bean 的集合,从这个集合中取出来的Bean可以立马返回
**earlySingletonObjects**
:二级缓存,存放创建好但没有初始化属性的Bean 的集合,它用来解决循环依赖
**singletonFactories**
:三级缓存,存放单实例Bean工厂 的集合
**singletonsCurrentlyInCreation**
:存放正在被创建的Bean 的集合
复制 /** Cache of singleton objects: bean name to bean instance. */
private final Map < String , Object > singletonObjects = new ConcurrentHashMap <>( 256 );
/** Cache of singleton factories: bean name to ObjectFactory. */
private final Map < String , ObjectFactory < ? >> singletonFactories = new HashMap <>( 16 );
/** Cache of early singleton objects: bean name to bean instance. */
private final Map < String , Object > earlySingletonObjects = new HashMap <>( 16 );
/** Names of beans that are currently in creation. */
private final Set < String > singletonsCurrentlyInCreation = Collections . newSetFromMap ( new ConcurrentHashMap <>( 16 ));
这几个成员相当重要,下面会慢慢看见他们。下面是 getSingleton
方法:
复制 public Object getSingleton( String beanName , ObjectFactory<?> singletonFactory) {
// ......
// 标记当前bean
beforeSingletonCreation(beanName) ;
// .....
try {
// 创建Bean
singletonObject = singletonFactory . getObject ();
newSingleton = true ;
}
// ......
}
beforeSingletonCreation
方法咱之前看过了:
复制 protected void beforeSingletonCreation( String beanName) {
if ( ! this . inCreationCheckExclusions . contains (beanName) && ! this . singletonsCurrentlyInCreation . add (beanName)) {
throw new BeanCurrentlyInCreationException(beanName) ;
}
}
它把当前的 cat 放入 singletonsCurrentlyInCreation
**(正在创建的Bean)**中。
接下来准备调用 singletonFactory.getObject()
,也就是调用下面的 createBean
方法:
3.3 createBean(cat)
复制 // AbstractAutowireCapableBeanFactory
protected Object createBean( String beanName , RootBeanDefinition mbd , @ Nullable Object [] args)
throws BeanCreationException {
// ......
try {
Object beanInstance = doCreateBean(beanName , mbdToUse , args) ;
if ( logger . isTraceEnabled ()) {
logger . trace ( "Finished creating instance of bean '" + beanName + "'" );
}
return beanInstance;
}
// ......
}
最终调到 doCreateBean
方法:
3.4 doCreateBean(cat) & createBeanInstance
复制 protected Object doCreateBean( final String beanName , final RootBeanDefinition mbd , final @ Nullable Object [] args)
throws BeanCreationException {
// ......
// 创建Bean实例
if (instanceWrapper == null ) {
instanceWrapper = createBeanInstance(beanName , mbd , args) ;
}
// ......
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
boolean earlySingletonExposure = ( mbd . isSingleton () && this . allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName) );
if (earlySingletonExposure) {
if ( logger . isTraceEnabled ()) {
logger . trace ( "Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references" );
}
addSingletonFactory(beanName , () -> getEarlyBeanReference(beanName , mbd , bean)) ;
}
// ......
Object exposedObject = bean;
try {
// 属性赋值&自动注入
populateBean(beanName , mbd , instanceWrapper) ;
exposedObject = initializeBean(beanName , exposedObject , mbd) ;
}
//......
return exposedObject;
}
Bean的实例化过程咱就不看了,当 createBeanInstance
方法运行完后,此时的cat中:
此时:这个cat被称为 “早期Bean” ,而且被包装为 BeanWrapper
。
继续往下走,中间有一个非常关键的步骤:earlySingletonExposure
的判断。
复制 protected Object doCreateBean( final String beanName , final RootBeanDefinition mbd , final @ Nullable Object [] args)
throws BeanCreationException {
// ......
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
boolean earlySingletonExposure = ( mbd . isSingleton () && this . allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName) );
if (earlySingletonExposure) {
if ( logger . isTraceEnabled ()) {
logger . trace ( "Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references" );
}
addSingletonFactory(beanName , () -> getEarlyBeanReference(beanName , mbd , bean)) ;
}
// ......
}
3.5 earlySingletonExposure的判断 & addSingletonFactory
这个判断非常关键,它要同时成立三个条件才能进if结构:
正在创建的单实例Bean对象中有当前的这个Bean
由于在3.2环节中,singletonsCurrentlyInCreation
这个集合中已经把 cat 放进去了,此时这个判断也为true 。
三个条件全为true,进入if结构中,它干了这么一件事:
复制 addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
来看 addSingletonFactory
的源码:
复制 protected void addSingletonFactory( String beanName , ObjectFactory<?> singletonFactory) {
Assert . notNull (singletonFactory , "Singleton factory must not be null" );
synchronized ( this . singletonObjects ) {
if ( ! this . singletonObjects . containsKey (beanName)) {
this . singletonFactories . put (beanName , singletonFactory);
this . earlySingletonObjects . remove (beanName);
this . registeredSingletons . add (beanName);
}
}
}
这一步的动作可以看出来,是将当前正在创建的Bean保存到三级缓存中,并从二级缓存中移除 (由于本来二级缓存中没有,故可以只认定为放入三级缓存)。
下面的属性赋值&自动注入点:
复制 protected Object doCreateBean( final String beanName , final RootBeanDefinition mbd , final @ Nullable Object [] args)
throws BeanCreationException {
// ......
try {
// 属性赋值&自动注入
populateBean(beanName , mbd , instanceWrapper) ;
exposedObject = initializeBean(beanName , exposedObject , mbd) ;
}
//......
return exposedObject;
}
3.6 populateBean(cat)
复制 protected void populateBean( String beanName , RootBeanDefinition mbd , @ Nullable BeanWrapper bw) {
// ......
PropertyDescriptor [] filteredPds = null ;
if (hasInstAwareBpps) {
if (pvs == null ) {
pvs = mbd . getPropertyValues ();
}
for ( BeanPostProcessor bp : getBeanPostProcessors() ) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
PropertyValues pvsToUse = ibp . postProcessProperties (pvs , bw . getWrappedInstance () , beanName);
if (pvsToUse == null ) {
if (filteredPds == null ) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw , mbd . allowCaching ) ;
}
pvsToUse = ibp . postProcessPropertyValues (pvs , filteredPds , bw . getWrappedInstance () , beanName);
if (pvsToUse == null ) {
return ;
}
}
pvs = pvsToUse;
}
}
}
//......
}
在这个 InstantiationAwareBeanPostProcessor
的for循环中,会调用 AutowiredAnnotationBeanPostProcessor
的 postProcessProperties
方法,触发自动注入。
3.7 AutowiredAnnotationBeanPostProcessor#postProcessProperties
复制 public PropertyValues postProcessProperties( PropertyValues pvs , Object bean , String beanName) {
InjectionMetadata metadata = findAutowiringMetadata(beanName , bean . getClass() , pvs) ;
try {
metadata . inject (bean , beanName , pvs);
}
catch ( BeanCreationException ex) {
throw ex;
}
catch ( Throwable ex) {
throw new BeanCreationException(beanName , "Injection of autowired dependencies failed" , ex) ;
}
return pvs;
}
在上面收集好要注入的属性后,下面的 metadata.inject
方法:
3.8 【注入】metadata.inject
跳转到 AutowiredFieldElement#inject
中:
复制 protected void inject( Object bean , @ Nullable String beanName , @ Nullable PropertyValues pvs) throws Throwable {
Field field = (Field) this . member ;
Object value;
// ......
try {
value = beanFactory . resolveDependency (desc , beanName , autowiredBeanNames , typeConverter);
}
// ......
if (value != null ) {
ReflectionUtils . makeAccessible (field);
field . set (bean , value);
}
}
一开始初始化的时候肯定找不到 Person ,要走 beanFactory.resolveDependency
方法:
3.9 beanFactory.resolveDependency
此时跳转到 DefaultListableBeanFactory
类中:
复制 public Object resolveDependency( DependencyDescriptor descriptor , @ Nullable String requestingBeanName ,
@ Nullable Set< String > autowiredBeanNames , @ Nullable TypeConverter typeConverter) throws BeansException {
descriptor . initParameterNameDiscovery ( getParameterNameDiscoverer() );
// if-else ......
else {
Object result = getAutowireCandidateResolver() . getLazyResolutionProxyIfNecessary (
descriptor , requestingBeanName);
if (result == null ) {
result = doResolveDependency(descriptor , requestingBeanName , autowiredBeanNames , typeConverter) ;
}
return result;
}
}
来到最后的 doResolveDependency
方法中:
3.10 doResolveDependency
复制 public Object doResolveDependency( DependencyDescriptor descriptor , @ Nullable String beanName ,
@ Nullable Set< String > autowiredBeanNames , @ Nullable TypeConverter typeConverter) throws BeansException {
// try ......
if (instanceCandidate instanceof Class) {
instanceCandidate = descriptor . resolveCandidate (autowiredBeanName , type , this );
}
// ......
}
Debug走到这一步,跳转进去的方法就是 getBean
:
4. 流程全分析 - 初始化Person
4.1 getBean(person)
复制 public Object resolveCandidate( String beanName , Class<?> requiredType , BeanFactory beanFactory)
throws BeansException {
return beanFactory . getBean (beanName);
}
继续往下走,回到 AbstractBeanFactory
了:
4.2 doGetBean(person) - getSingleton(person)
与上面的思路类似,不再贴源码,当执行到getSingleton方法时,要知道 beforeSingletonCreation 方法又执行了,此时正在创建的Bean有两个了:
4.3 createBean(person) - doCreateBean(person) -> addSingletonFactory
这几步操作最终完成的动作:将person放入三级缓存,并从二级缓存中移除 。
4.4 populateBean(person)
跟上面一样,也是同样的执行后置处理器,走inject方法。
4.5 metadata.inject - resolveDependency - doResolveDependency
最终也会像上面一样,执行到这一步:
复制 public Object doResolveDependency( DependencyDescriptor descriptor , @ Nullable String beanName ,
@ Nullable Set< String > autowiredBeanNames , @ Nullable TypeConverter typeConverter) throws BeansException {
// try ......
if (instanceCandidate instanceof Class) {
instanceCandidate = descriptor . resolveCandidate (autowiredBeanName , type , this );
}
// ......
}
进去会调getBean(cat)。
4.6 再次getBean(cat)
其实这里进的还是我们熟悉的那个getBean:
复制 public Object getBean( String name) throws BeansException {
return doGetBean(name , null , null , false ) ;
}
下面还是那一套,不过进入 doGetBean
方法后有一个很重要的环节:**getSingleton**
4.7 【二次获取】getSingleton(cat)
复制 protected Object getSingleton( String beanName , boolean allowEarlyReference) {
Object singletonObject = this . singletonObjects . get (beanName);
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName) ) {
synchronized ( this . singletonObjects ) {
singletonObject = this . earlySingletonObjects . get (beanName);
if (singletonObject == null && allowEarlyReference) {
ObjectFactory < ? > singletonFactory = this . singletonFactories . get (beanName);
if (singletonFactory != null ) {
singletonObject = singletonFactory . getObject ();
this . earlySingletonObjects . put (beanName , singletonObject);
this . singletonFactories . remove (beanName);
}
}
}
}
return singletonObject;
}
注意在这里第二次获取 cat 的时候,由于现在 正在被创建的Bean 中有 cat 了,所以 isSingletonCurrentlyInCreation(cat)
将返回true!会进入到下面的if结构体中!
进入之后,它要确定 **earlySingletonObjects**
二级缓存 中是否有当前创建好但没有赋值初始化的Bean (当前cat),此时根据前面的步骤,person和cat均只在三级缓存,所以取出的 singletonObject
为null,进入第二层if的结构体中。再往下来,它又从 **singletonFactories**
三级缓存 中取当前正在创建的Bean (cat),这次可以查到,于是进入第三层if的结构体。它干了两件事:将这个 cat 放入二级缓存,并从三级缓存中移除 。
操作完成后的状态:
那既然这里已经获取到了,那 singletonObject
自然有值,就可以正常返回那个 正在创建,但还没有注入依赖项的cat 。
4.8 回到doGetBean(cat)
复制 Object sharedInstance = getSingleton(beanName) ;
if (sharedInstance != null && args == null ) {
// log ......
bean = getObjectForBeanInstance(sharedInstance , name , beanName , null ) ;
}
获取到 cat 后,下面会调用一个 getObjectForBeanInstance
方法:
4.9 getObjectForBeanInstance(cat)
复制 private final NamedThreadLocal < String > currentlyCreatedBean = new NamedThreadLocal <>( "Currently created bean" );
protected Object getObjectForBeanInstance(
Object beanInstance , String name , String beanName , @ Nullable RootBeanDefinition mbd) {
String currentlyCreatedBean = this . currentlyCreatedBean . get ();
if (currentlyCreatedBean != null ) {
registerDependentBean(beanName , currentlyCreatedBean) ;
}
return super . getObjectForBeanInstance (beanInstance , name , beanName , mbd);
}
这里先通过 this.currentlyCreatedBean.get()
取到当前线程中正在创建的Bean的名称,发现为null(到目前为止也没发现谁在操作它,通过IDEA的提示,发现是 obtainFromSupplier
方法中有对它的操作,之前提过了我们不关心它),则直接调父类的 getObjectForBeanInstance
方法:
4.10 AbstractBeanFactory#getObjectForBeanInstance(cat)
复制 protected Object getObjectForBeanInstance(
Object beanInstance , String name , String beanName , @ Nullable RootBeanDefinition mbd) {
// Don't let calling code try to dereference the factory if the bean isn't a factory.
// 如果Bean不是工厂,则不要让调用代码尝试取消引用工厂
if ( BeanFactoryUtils . isFactoryDereference (name)) {
if (beanInstance instanceof NullBean) {
return beanInstance;
}
if ( ! (beanInstance instanceof FactoryBean)) {
throw new BeanIsNotAFactoryException(beanName , beanInstance . getClass()) ;
}
}
// Now we have the bean instance, which may be a normal bean or a FactoryBean.
// If it's a FactoryBean, we use it to create a bean instance, unless the
// caller actually wants a reference to the factory.
if ( ! (beanInstance instanceof FactoryBean) || BeanFactoryUtils . isFactoryDereference (name)) {
return beanInstance;
}
// ......
}
第一段if中,因为 cat 不是被工厂引用的Bean,这部分不进入。
第二段if中,因为 cat 不是一个工厂Bean,前半段返回true,直接返回cat。
这段方法走完后,cat还是那个cat。
回到doGetBean方法:
4.11 再回到doGetBean(cat)
复制 // Check if required type matches the type of the actual bean instance.
// 检查所需的类型是否与实际bean实例的类型匹配
if (requiredType != null && ! requiredType . isInstance (bean)) {
// ......
}
return (T) bean;
这一段if判断是确定bean与返回的类型是否一致,这里很明显一致,直接强转返回即可。
4.12 回到注入的部分(person)
复制 public Object doResolveDependency( DependencyDescriptor descriptor , @ Nullable String beanName ,
@ Nullable Set< String > autowiredBeanNames , @ Nullable TypeConverter typeConverter) throws BeansException {
// ......
if (instanceCandidate instanceof Class) {
instanceCandidate = descriptor . resolveCandidate (autowiredBeanName , type , this );
}
Object result = instanceCandidate;
if (result instanceof NullBean) {
if ( isRequired(descriptor) ) {
raiseNoMatchingBeanFound(type , descriptor . getResolvableType() , descriptor) ;
}
result = null ;
}
if ( ! ClassUtils . isAssignableValue (type , result)) {
throw new BeanNotOfRequiredTypeException(autowiredBeanName , type , instanceCandidate . getClass()) ;
}
return result;
}
finally {
ConstructorResolver . setCurrentInjectionPoint (previousInjectionPoint);
}
}
descriptor.resolveCandidate
方法执行完后,下面把bean交给result,确定没问题,返回出去。
4.13 回到resolveDependency(person)
复制 public Object resolveDependency( DependencyDescriptor descriptor , @ Nullable String requestingBeanName ,
@ Nullable Set< String > autowiredBeanNames , @ Nullable TypeConverter typeConverter) throws BeansException {
// if-else ......
else {
Object result = getAutowireCandidateResolver() . getLazyResolutionProxyIfNecessary (
descriptor , requestingBeanName);
if (result == null ) {
result = doResolveDependency(descriptor , requestingBeanName , autowiredBeanNames , typeConverter) ;
}
return result;
}
}
这个方法也就成功返回cat了。
4.14 返回inject方法(person)
复制 protected void inject( Object bean , @ Nullable String beanName , @ Nullable PropertyValues pvs) throws Throwable {
// ......
try {
value = beanFactory . resolveDependency (desc , beanName , autowiredBeanNames , typeConverter);
}
// ......
}
if (value != null ) {
ReflectionUtils . makeAccessible (field);
field . set (bean , value);
}
}
取到value,也就是那个cat的Bean后,最底下利用反射赋值,自动注入结束。
此时二级缓存和三级缓存中还是那个状态:
4.15 回到doCreateBean(person)
复制 protected Object doCreateBean( final String beanName , final RootBeanDefinition mbd , final @ Nullable Object [] args)
throws BeanCreationException {
// ......
Object exposedObject = bean;
try {
populateBean(beanName , mbd , instanceWrapper) ;
exposedObject = initializeBean(beanName , exposedObject , mbd) ;
}
//......
return exposedObject;
}
person的属性赋值和自动注入完成后,执行初始化方法(没定义),最后返回出去。
4.16 回到createBean(person)
复制 protected Object createBean( String beanName , RootBeanDefinition mbd , @ Nullable Object [] args)
throws BeanCreationException {
// ......
try {
Object beanInstance = doCreateBean(beanName , mbdToUse , args) ;
// log ......
return beanInstance;
}
// ......
}
也是直接返回出去。
4.17 回到DefaultSingletonBeanRegistry#getSingleton(person)
复制 public Object getSingleton( String beanName , ObjectFactory<?> singletonFactory) {
// ......
try {
singletonObject = singletonFactory . getObject ();
newSingleton = true ;
}
// catch ......
finally {
if (recordSuppressedExceptions) {
this . suppressedExceptions = null ;
}
afterSingletonCreation(beanName) ;
}
if (newSingleton) {
addSingleton(beanName , singletonObject) ;
}
}
return singletonObject;
}
}
createBean
返回后回到Lambda表达式,又回到 getSingleton
方法中。创建的这个单实例Person 会被 newSingleton
标记为true,在下面的finally块中,要执行两个重要的方法:afterSingletonCreation
和 addSingleton
:
4.18 afterSingletonCreation
复制 protected void afterSingletonCreation( String beanName) {
if ( ! this . inCreationCheckExclusions . contains (beanName) && ! this . singletonsCurrentlyInCreation . remove (beanName)) {
throw new IllegalStateException( "Singleton '" + beanName + "' isn't currently in creation" ) ;
}
}
这部分的作用:将创建好的Bean从“正在创建中的Bean”中移除 。
4.19 【重要】addSingleton
复制 protected void addSingleton( String beanName , Object singletonObject) {
synchronized ( this . singletonObjects ) {
this . singletonObjects . put (beanName , singletonObject);
this . singletonFactories . remove (beanName);
this . earlySingletonObjects . remove (beanName);
this . registeredSingletons . add (beanName);
}
}
这部分的作用:将创建的这个Bean放入一级缓存,从二级缓存和三级缓存中移除,并记录已经创建了的单实例Bean 。
至此,Person的创建完全结束。
5. 回到Cat的创建
5.1 回到DependencyDescriptor#resolveCandidate(cat)
复制 public Object resolveCandidate( String beanName , Class<?> requiredType , BeanFactory beanFactory)
throws BeansException {
return beanFactory . getBean (beanName);
}
这个 getBean(person)
结束了,真正完全创建好的Person也返回来了。下面的步骤就与上面一样了,快速过一遍。
5.2 返回注入的部分(cat)
复制 public Object doResolveDependency( DependencyDescriptor descriptor , @ Nullable String beanName ,
@ Nullable Set< String > autowiredBeanNames , @ Nullable TypeConverter typeConverter) throws BeansException {
// ......
if (instanceCandidate instanceof Class) {
// person
instanceCandidate = descriptor . resolveCandidate (autowiredBeanName , type , this );
}
Object result = instanceCandidate;
// ......
return result;
}
// ......
}
5.3 回到resolveDependency(cat)
复制 public Object resolveDependency( DependencyDescriptor descriptor , @ Nullable String requestingBeanName ,
@ Nullable Set< String > autowiredBeanNames , @ Nullable TypeConverter typeConverter) throws BeansException {
// if-else ......
else {
Object result = getAutowireCandidateResolver() . getLazyResolutionProxyIfNecessary (
descriptor , requestingBeanName);
if (result == null ) {
// person
result = doResolveDependency(descriptor , requestingBeanName , autowiredBeanNames , typeConverter) ;
}
return result;
}
}
5.4 返回inject方法(cat)
复制 protected void inject( Object bean , @ Nullable String beanName , @ Nullable PropertyValues pvs) throws Throwable {
// ......
try {
// person
value = beanFactory . resolveDependency (desc , beanName , autowiredBeanNames , typeConverter);
}
// ......
}
if (value != null ) {
//缓存person
ReflectionUtils . makeAccessible (field);
field . set (bean , value);
}
}
5.5 回到doCreateBean(cat)
复制 protected Object doCreateBean( final String beanName , final RootBeanDefinition mbd , final @ Nullable Object [] args)
throws BeanCreationException {
// ......
Object exposedObject = bean;
try {
// 自动注入完成
populateBean(beanName , mbd , instanceWrapper) ;
exposedObject = initializeBean(beanName , exposedObject , mbd) ;
}
//......
return exposedObject;
}
5.6 回到createBean(cat)
复制 protected Object createBean( String beanName , RootBeanDefinition mbd , @ Nullable Object [] args)
throws BeanCreationException {
// ......
try {
Object beanInstance = doCreateBean(beanName , mbdToUse , args) ;
// log ......
// 直接返回出去了
return beanInstance;
}
// ......
}
5.7 回到DefaultSingletonBeanRegistry#getSingleton(cat)
复制 public Object getSingleton( String beanName , ObjectFactory<?> singletonFactory) {
// ......
try {
singletonObject = singletonFactory . getObject ();
newSingleton = true ;
}
// catch ......
finally {
if (recordSuppressedExceptions) {
this . suppressedExceptions = null ;
}
// 清除正在创建的缓存
afterSingletonCreation(beanName) ;
}
if (newSingleton) {
// 创建完cat后也要调这个方法
addSingleton(beanName , singletonObject) ;
}
}
return singletonObject;
}
}
5.8 afterSingletonCreation
复制 protected void afterSingletonCreation( String beanName) {
// 清除正在创建的缓存
if ( ! this . inCreationCheckExclusions . contains (beanName) && ! this . singletonsCurrentlyInCreation . remove (beanName)) {
throw new IllegalStateException( "Singleton '" + beanName + "' isn't currently in creation" ) ;
}
}
5.9 【重要】addSingleton
复制 protected void addSingleton( String beanName , Object singletonObject) {
synchronized ( this . singletonObjects ) {
// 将cat放入一级缓存
this . singletonObjects . put (beanName , singletonObject);
// 从二级缓存和三级缓存中移除
this . singletonFactories . remove (beanName);
this . earlySingletonObjects . remove (beanName);
// 记录已经创建了的cat
this . registeredSingletons . add (beanName);
}
}
至此,Cat的创建完全结束。
6. @Autowired解决循环依赖的核心思路
整个IOC容器解决循环依赖,用到的几个重要成员:
**singletonObjects**
:一级缓存,存放完全初始化好的Bean 的集合,从这个集合中取出来的Bean可以立马返回
**earlySingletonObjects**
:二级缓存,存放创建好但没有初始化属性的Bean 的集合,它用来解决循环依赖
**singletonFactories**
:三级缓存,存放单实例Bean工厂 的集合
**singletonsCurrentlyInCreation**
:存放正在被创建的Bean 的集合
咱来总结一下,IOC容器解决循环依赖的思路:
初始化 Bean 之前,将这个 bean 的 name 放入三级缓存
创建 Bean 将准备创建的 Bean 放入 singletonsCurrentlyInCreation (正在创建的 Bean )
createNewInstance
方法执行完后执行 addSingletonFactory
,将这个实例化但没有属性赋值的 Bean 放入三级缓存,并从二级缓存中移除
一般情况下初次创建的 bean 不会存在于二级缓存,故该步骤可以简单理解为仅仅是放入了三级缓存而已
检查“正在被创建的 Bean ”中是否有即将注入的 Bean
如果有,检查二级缓存中是否有当前创建好但没有赋值初始化的 Bean
如果没有,检查三级缓存中是否有正在创建中的 Bean
至此一般会有,将这个 Bean 放入二级缓存,并从三级缓存中移除
之后 Bean 被成功注入,最后执行 addSingleton
,将这个完全创建好的Bean放入一级缓存,从二级缓存和三级缓存移除 ,并记录已经创建了的单实例Bean
下面的这张图描述了上述的过程,图很大,建议用原图查看更佳: