多图详解Spring框架

  下面看一下Context和Resource是如何建立关系的?首先看一下他们的类关系图:

物联网

  图9.Context和Resource的类关系图

  从上图可以看出,Context是把资源的加载、解析和描述工作委托给了ResourcePatternResolver类来完成,他相当于一个接头人,他把资源的加载、解析和资源的定义整合在一起便于其他组件使用。 Core组件中还有很多类似的方式。

  Ioc容器如何工作

  前面介绍了Core组件、Bean组件和Context组件的结构与相互关系,下面这里从使用者角度看一下他们是如何运行的,以及我们如何让Spring完成各种功能,Spring到底能有那些功能,这些功能是如 何得来的,下面介绍。

  如何创建BeanFactory工厂

  正如图2描述的那样,Ioc容器实际上就是Context组件结合其他两个组件共同构建了一个Bean关系网,如何构建这个关系网?构建的入口就在AbstractApplicationContext类的refresh方法中。这个方 法的代码如下:

  清单1.AbstractApplicationContext.refresh

  public void refresh() throws BeansException, IllegalStateException {

  synchronized (this.startupShutdownMonitor) {

  // Prepare this context for refreshing.

  prepareRefresh();

  // Tell the subclass to refresh the internal bean factory.

  ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

  // Prepare the bean factory for use in this context.

  prepareBeanFactory(beanFactory);

  try {

  // Allows post- processing of the bean factory in context subclasses.

  postProcessBeanFactory(beanFactory);

  // Invoke factory processors registered as beans in& nbsp;the context.

  invokeBeanFactoryPostProcessors(beanFactory);

  // Register bean processors that intercept bean crea tion.

  registerBeanPostProcessors (beanFactory);

  // Initialize message source for this context.

  initMessageSource();

  // Initialize event multicaster for this context.

  initApplicationEventMulticaster();

  // Initialize other special beans in specific contex t subclasses.

  onRefresh();

  // Check for listener beans and register them.

  registerListeners();

  // Instantiate all remaining (non-lazy-init) singletons.

  finishBeanFactoryInitialization (beanFactory);

  // Last step: publish corresponding event.

  finishRefresh();

  }

  catch (BeansException ex) {

  // Destroy already created singletons to avoid dangl ing resources.

  destroyBeans();

  // Reset 'active' flag.

  cancelRefresh(ex);

  // Propagate exception to caller.

  throw ex;

  }

  }

  }

  这个方法就是构建整个Ioc容器过程的完整的代码,了解了里面的每一行代码基本上就了解大部分Spring的原理和功能了。

  这段代码主要包含这样几个步骤:

  ◆构建BeanFactory,以便于产生所需的“演员”

  ◆注册可能感兴趣的事件

  ◆创建Bean实例对象

  ◆触发被监听的事件

  下面就结合代码分析这几个过程。

  第二三句就是在创建和配置BeanFactory。这里是refresh也就是刷新配置,前面介绍了Context有可更新的子类,这里正是实现这个功能,当BeanFactory已存在是就更新,如果没有就新创建。下面是 更新BeanFactory的方法代码:

  清单2. AbstractRefreshableApplicationContext. refreshBeanFactory

  protected final void refreshBeanFactory() throws BeansException {

  if (hasBeanFactory()) {

  destroyBeans();

  closeBeanFactory();

  }

  try {

  DefaultListableBeanFactory beanFactory = createBeanFactory();

  beanFactory.setSerializationId(getId());

  customizeBeanFactory(beanFactory);

  loadBeanDefinitions(beanFactory);

  synchronized (this.beanFactoryMonitor) {

  this.beanFactory = beanFactory;

  }

  }

  catch (IOException ex) {

  throw new ApplicationContextException(

  "I/O error& nbsp;parsing bean definition source for "

  + getDisplayName (), ex);

  }

  }

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