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

2020-02-21 22:17

这个方法实现了AbstractApplicationContext的抽象方法refreshBeanFactory,这段代码清楚的说明了BeanFactory的创建过程。注意BeanFactory类型的变化,前面介绍了它有很多子类,在什么情况下使用不同的子类这非常关键。BeanFactory的原始对象是DefaultListableBeanFactory。这非常关键,因为它涉及到后面对这个对象的多种操作,下面看一下这个类的继承层次类图:

图10. DefaultListableBeanFactory类继承关系图

从这个可以发现除了BeanFactory相关的类外,还有与Bean的register相关的类。这在

refreshBeanFactory方法中有一行loadBeanDefinations(beanFactory)将找到答案,这个方法将开始加载,解析Bean的定义,也就是把用户定义的数据结构转化成IOC中特定的数据结构。

这个过程可以用下面的时序图来解释:

图11. 创建BeanFactory时序图

Bean的解析和登记流程时序图如下:

图12.解析和登记Bean对象时序图

创建好BeanFactory后,接下来添加一些Spring本身需要的工具类,这个操作在AbstractApplicationContext的prepareBeanFactory方法完成。

AbstractApplicationContext中接下来三行代码对Spring的功能扩展起了至关重要的作用。前两行主要是让你现在可以对已经创建的BeanFactory的配置做修改,后一行就是让你可以对以后再创建Bean的实例对象时添加一些自定义的操作。所以他们都是扩展了Spring的功能,也必须要把这一部分搞清楚。

其中invokeBeanFactoryPostProcessors方法主要是获取实现BeanFactoryPostProcessor接口的子类,并执行它的postProcessBeanFactory方法,这个方法的声明如下:

清单3. BeanFactoryPostProcessor.postProcessBeanFactory

void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;

他的参数是beanFactory,说明可以对beanFactory做修改,这里注意这个beanFactory是

ConfigurableListableBeanFactory类型的,这也印证了前面介绍的不同BeanFactory所使用的场合不同,这里只能是可配置的BeanFactory,防止一些数据被用户随意修改。

registerBeanPostProcessors方法也是可以获取用户定义的实现了BeanPostProcessor接口的子类,并执行把它们注册到BeanFactory对象中的beanPostProcessors变量中。BeanPostProcessor接口中声明了两个方法:postProcessBeforeInitialization和postProcessAfterInitialization分别用于Bean对象初始化时执行,可以执行用户自定义的操作。

后面的几行代码是初始化监听事件和对系统的其他监听者的注册,监听者必须是ApplicationListener的子类。

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

下面就是Bean的实例化代码,是从finishBeanFactoryInitialization方法开始的。 清单4. AbstractApplicationContext.finishBeanFactoryInitialization

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {

//stop using temporary ClassLoader for type matching

beanFactory.setTempClassLoader(null);

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

//Instantiate all remaining(not-lazy-init) singletons

beanFactory.preInstantiateSingletons(); }

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

public void preInstantiateSingletons() throws BeansException {

if (this.logger.isInfoEnabled()) { }

synchronized (this.beanDefinitionMap) {

for (Iterator it = this.beanDefinitionNames.iterator(); this.logger.info(\

it.hasNext();) {

String beanName = (String) it.next();

RootBeanDefinition bd =

getMergedLocalBeanDefinition(beanName); {

if (isFactoryBean(beanName)) {

FactoryBean factory = (FactoryBean)

if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit())

getBean(FACTORY_BEAN_PREFIX + beanName);

if (factory instanceof SmartFactoryBean &&

((SmartFactoryBean) factory).isEagerInit()) { }

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

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

}

}

}

} else { }

}

getBean(beanName);

getBean(beanName);

图13.Bean 实例创建流程图

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


Spring框架的设计理念与设计模式分析(3).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:留学生求职除了排队交简历,春招 Career Fair 上你还该做什么?

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: