Spring框架学习[IoC容器高级特性](三)

2014-11-24 03:11:10 · 作者: · 浏览: 6
sSingletonCurrentlyInCreation(beanName)) {
  • logger.debug(Returning eagerly cached instance of singleton bean ' + beanName + ' that is not fully initialized yet - a consequence of a circular reference);
  • } else {
  • logger.debug(Returning cached instance of singleton bean ' + beanName + '); }
  • } //获取给定Bean的实例对象,主要是完成FactoryBean的相关处理
  • bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); }
  • …… }
  • //获取给定Bean的实例对象,主要是完成FactoryBean的相关处理 protected Object getObjectForBeanInstance( Object beanInstance, String name, String beanName, RootBeanDefinition mbd) {
  • //容器已经得到了Bean实例对象,这个实例对象可能是一个普通的Bean,也可能是 //一个工厂Bean,如果是一个工厂Bean,则使用它创建一个Bean实例对象,如果
  • //调用本身就想获得一个容器的引用,则指定返回这个工厂Bean实例对象 //如果指定的名称是容器的解引用(dereference,即是对象本身而非内存地址),
  • //且Bean实例也不是创建Bean实例对象的工厂Bean if (BeanFactoryUtils.isFactoryDereference(name) && !(beanInstance instanceof FactoryBean)) {
  • throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass()); }
  • //如果Bean实例不是工厂Bean,或者指定名称是容器的解引用,调用者向获取对 //容器的引用,则直接返回当前的Bean实例
  • if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) { return beanInstance;
  • } //处理指定名称不是容器的解引用,或者根据名称获取的Bean实例对象是一个工厂Bean
  • //使用工厂Bean创建一个Bean的实例对象 Object object = null;
  • if (mbd == null) { //从Bean工厂缓存中获取给定名称的Bean实例对象
  • object = getCachedObjectForFactoryBean(beanName); }
  • //让Bean工厂生产给定名称的Bean对象实例 if (object == null) {
  • FactoryBean factory = (FactoryBean) beanInstance; //如果从Bean工厂生产的Bean是单态模式的,则缓存
  • if (mbd == null && containsBeanDefinition(beanName)) { //从容器中获取指定名称的Bean定义,如果继承基类,则合并基类相关属性
  • mbd = getMergedLocalBeanDefinition(beanName); }
  • //如果从容器得到Bean定义信息,并且Bean定义信息不是虚构的,则让工厂 //Bean生产Bean实例对象
  • boolean synthetic = (mbd != null && mbd.isSynthetic()); //调用FactoryBeanRegistrySupport类的getObjectFromFactoryBean
  • //方法,实现工厂Bean生产Bean对象实例的过程 object = getObjectFromFactoryBean(factory, beanName, !synthetic);
  • } return object;
  • }

    在上面获取给定Bean的实例对象的getObjectForBeanInstance方法中,会调用FactoryBeanRegistrySupport类的getObjectFromFactoryBean方法,该方法实现了Bean工厂生产Bean实例对象。

    Dereference(解引用):一个在C/C++中应用比较多的术语,在C++中,”*”是解引用符号,而”&”是引用符号,解引用是指变量指向的是所引用对象的本身数据,而不是引用对象的内存地址。

    (3). AbstractBeanFactory生产Bean实例对象:

    AbstractBeanFactory类中生产Bean实例对象的主要源码如下:

    [java]
    1. //Bean工厂生产Bean实例对象 protected Object getObjectFromFactoryBean(FactoryBean factory, String beanName, boolean shouldPostProcess) {
    2. //Bean工厂是单态模式,并且Bean工厂缓存中存在指定名称的Bean实例对象 if (factory.isSingleton() && containsSingleton(beanName)) {
    3. //多线程同步,以防止数据不一致 synchronized (getSingletonMutex()) {
    4. //直接从Bean工厂缓存中获取指定名称的Bean实例对象 Object object = this.factoryBeanObjectCache.get(beanName);
    5. //Bean工厂缓存中没有指定名称的实例对象,则生产该实例对象 if (object == null) {
    6. //调用Bean工厂的getObject方法生产指定Bean的实例对象 object = doGetObjectFromFactoryBean(factory, beanName, shouldPostProcess);
    7. //将生产的实例对象添加到Bean工厂缓存中 this.factoryBeanObjectCache.put(beanName, (object != null object : NULL_OBJECT));
    8. } return (object != NULL_OBJECT object : null);
    9. } }
    10. //调用Bean工厂的getObject方法生产指定Bean的实例对象 else {
    11. return doGetObjectFromFactoryBean(factory, beanName, shouldPostProcess); }
    12. } //调用Bean工厂的getObject方法生产指定Bean的实例对象
    13. private Object doGetObjectFromFactoryBean( final FactoryBean factory, final String beanName, final boolean shouldPostProcess)
    14. throws BeanCreationException { Object object;
    15. try { if (Syst