【知识库】--spring 记录创建bean(单例)的ObjectFactory(240)

来源:互联网 发布:朋友圈砍价软件 编辑:程序博客网 时间:2024/05/21 14:53

ObjectFactory作用:单例提前曝光--singleton循环依赖


doCreateBean中代码片段


boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName));//在创建的单例允许循环依赖


if(earlySingletonExposure){

           //在bean初始化完成之前将创建的ObjectFactory加入工厂--循环依赖

          addSingletonFactory(beanName,new ObjectFactory(){// 注册回调

                      public Object getObject() throws BeansException{

                             //主要应用SmartInstantiationAwareBeanPostProcessor, AOP将advice动态织入bean中

                             return getEarlyBeanReference(beanName,mbd,bean);

                     }

           });

}


回调代码:

protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean){

               Object exposedObject = bean;

                if(bean!=null && !mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()){

                     //增强处理  AOP动态织入

                    for(BeanPostProcessor bp : getBeanPostProcessors()){

                            if(bp instanceof SmartInstantiationAwareBeanPostProcessor){

                                  SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;

                                  exposedObject = ibp.getEarlyBeanReference(exposedObject,beanName);

                                  if(exposedObject == null){ 

                                        return exposedObject;

                                  }

                            }

                    }

               }

              return exposedObject;

}


注意:1.this.allowCircularReferences 可以通过硬编码方式进行设置或者自定义命名空间进行配置,硬编码格式:

           ClassPathXmlApplicationContext cnx = new ClassPathXmlApplicationContext("app.xml");

           cnx.setAllowCircularReferences(false);

          2. 如何标记某个单例正在创建中呢?

           singleton记录属性的函数是在:DefaultSingletonBeanRegistry中的函数:

                 public Object getSingleton(String beanName, ObjectFactory singletonFactory)中:

                      beforeSingletonCreation(beanName) , afterSingletonCreation(beanName)中:

                                this.singletonsCurrentlyInCreation.add(beanName),this.singletonsCurrentlyInCreation.remove(beanName);

                2.1 DefaultSingletonBeanRegistry 单例注册中心,各种缓存。

           3.回调什么时候会触发? A-->B-->C-->A

             循环依赖的末尾C会通过:getBean(A)触发回调,结束递归创建。--解决依赖

              






阅读全文
0 0