技术开发 频道

Spring 框架的设计理念与设计模式分析

  如何创建 Bean 实例并构建 Bean 的关系网

  下面就是 Bean 的实例化代码,是从 finishBeanFactoryInitialization 方法开始的。

  清单 4. AbstractApplicationContext.finishBeanFactoryInitialization

protected void finishBeanFactoryInitialization(
    ConfigurableListableBeanFactory beanFactory) {

    
// Stop using the temporary ClassLoader for type matching.
    beanFactory.setTempClassLoader(null);

    
// Allow for caching all bean definition metadata, not expecting further changes.
    beanFactory.freezeConfiguration();

    
// Instantiate all remaining (non-lazy-init) singletons.
    beanFactory.preInstantiateSingletons();
}

 

  从上面代码中可以发现 Bean 的实例化是在 BeanFactory 中发生的。preInstantiateSingletons 方法的代码如下:

  清单 5. DefaultListableBeanFactory.preInstantiateSingletons

public void preInstantiateSingletons() throws BeansException {
    
if (this.logger.isInfoEnabled()) {
        
this.logger.info("Pre-instantiating singletons in " + this);
    }
    
synchronized (this.beanDefinitionMap) {
        
for (String beanName : this.beanDefinitionNames) {
            RootBeanDefinition bd
= getMergedLocalBeanDefinition(beanName);
            
if (!bd.isAbstract() && bd.isSingleton()
                
&& !bd.isLazyInit()) {
                
if (isFactoryBean(beanName)) {
                    
final FactoryBean factory =
                        (FactoryBean) getBean(FACTORY_BEAN_PREFIX
+ beanName);
                    
boolean isEagerInit;
                    
if (System.getSecurityManager() != null
                        
&& factory instanceof SmartFactoryBean) {
                        isEagerInit
= AccessController.doPrivileged(
                            
new PrivilegedAction<Boolean>() {
                            
public Boolean run() {
                                
return ((SmartFactoryBean) factory).isEagerInit();
                            }
                        }, getAccessControlContext());
                    }
                    
else {
                        isEagerInit
= factory instanceof SmartFactoryBean
                            
&& ((SmartFactoryBean) factory).isEagerInit();
                    }
                    
if (isEagerInit) {
                        getBean(beanName);
                    }
                }
                
else {
                    getBean(beanName);
                }
            }
        }
    }
}

 

  这里出现了一个非常重要的 Bean —— FactoryBean,可以说 Spring 一大半的扩展的功能都与这个 Bean 有关,这是个特殊的 Bean 他是个工厂 Bean,可以产生 Bean 的 Bean,这里的产生 Bean 是指 Bean 的实例,如果一个类继承 FactoryBean 用户可以自己定义产生实例对象的方法只要实现他的 getObject 方法。然而在 Spring 内部这个 Bean 的实例对象是 FactoryBean,通过调用这个对象的 getObject 方法就能获取用户自定义产生的对象,从而为 Spring 提供了很好的扩展性。Spring 获取 FactoryBean 本身的对象是在前面加上 & 来完成的。

  如何创建 Bean 的实例对象以及如何构建 Bean 实例对象之间的关联关系式 Spring 中的一个核心关键,下面是这个过程的流程图。

  图 13.Bean 实例创建流程图

 如何创建Bean实例并构建 Bean 的关系网

  如果是普通的 Bean 就直接创建他的实例,是通过调用 getBean 方法。下面是创建 Bean 实例的时序图:

  图 14.Bean 实例创建时序图

 如何创建Bean实例并构建 Bean 的关系网

  还有一个非常重要的部分就是建立 Bean 对象实例之间的关系,这也是 Spring 框架的核心竞争力,何时、如何建立他们之间的关系请看下面的时序图:

  图 15.Bean 对象关系建立

 如何创建Bean实例并构建 Bean 的关系网

0
相关文章