Spring-IOC之DefaultListableBeanFactory

  DefaultListableBeanFactory是一个可以独立运行使用的默认IOC容器实现类。它通过与BeanDefinitionReader建立依赖关系后,在启动期间可对事先准备的元数据(Configuration MetaData,如XML配置信息等)进行加载解析,将解析后得到的BeanDefinition信息编组成BeanDefinitionHolder对象,最后再将编组对象注册到DefaultListableBeanFactory的本地缓存中。
  当DefaultListableBeanFactory拥有必要的装配信息后,可通过getBean方法获取按照装配信息所生产的Bean实例。

类结构关系和作用

Spring-IOC之DefaultListableBeanFactory_第1张图片
  如上图所示,DefaultListableBeanFactory作为Bean实例的装配工厂主要由如下15个关键组件共同实现。

接口/实现类 作用和特点

BeanFactory

基础IOC容器接口,提供访问Bean实例的方法等。

HierarchicalBeanFactory

继承BeanFactory,实现BeanFactory的分层结构关系。

AutowireCapableBeanFactory

继承BeanFactory,实现Bean的自动装配功能。

ListableBeanFactory

1.继承BeanFactory,实现Bean的集合操作功能;
2.当Bean实例以散列表(Map)形式存储在容器内时,通过此接口可获取更为丰富的Bean实例信息,例如通过getBeanDefinitionCount方法获取注册在案的Bean实例个数等。

ConfigurableBeanFactory

继承HierarchicalBeanFactory,在分层基础上实现BeanFactory的配置管理功能。

ConfigurableListableBeanFactory

继承ListableBeanFactory、AutowireCapableBeanFactory和ConfigurableListableBeanFactory接口,具备这三个接口功能的同时还提供了以下功能:
1.分析和修改BeanDefinition;
2. 预先实例化单例Bean对象。

AliasRegistry

注册BeanDefinition的“别名:名称”映射信息。

SingletonBeanRegistry

注册单例Bean实例。

BeanDefinitionRegistry

注册经解析后的BeanDefinition。

SimpleAliasRegistry

AliasRegistry的实现类,将BeanDefinition的“别名:名称”映射信息注册到aliasMap中。

DefaultSingletonBeanRegistry

SingletonBeanRegistry的实现类,除具备SimpleAliasRegistry的功能外,还可以将“Bean实例名称:Bean实例对象”注册到singletonObjects映射集中。

FactoryBeanRegistrySupport

1.继承DefaultSingletonBeanRegistry,实现对FactoryBean的注册功能;
2.FactoryBean之所以可以像普通Bean那样被注入到IOC容器中,FactoryBeanRegistrySupport的getCachedObjectForFactoryBean和getObjectFromFactoryBean方法在此发挥了关键作用。当容器调用AbstractBeanFactory的doGetBean方法获取Bean实例时,如果在内部的getObjectForBeanInstance方法中判断出目标实例是一个FactoryBean,则会根据实际情况调用这两个方法,尝试从本地缓存映射集(factoryBeanObjectCache)中获取对应的FactoryBean实例。

AbstractBeanFactory

继承FactoryBeanRegistrySupport并实现ConfigurableBeanFactory,因此具备单例Bean的注册和配置管理能力。

AbstractAutowireCapableBeanFactory

继承AbstractBeanFactory并实现AutowireCapableBeanFactory,因此在AbstractBeanFactory基础上又实现了Bean的自动装配功能。

Serializable

基于Serializable接口支持序列化/反序列操作,可在网络上传输。

实例化策略

  通常可通过如下两种策略来创建DefaultListableBeanFactory容器实例。

  1. 直接实例化DefaultListableBeanFactory;
// 构建DefaultListableBeanFactory实例
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
/* 通过BeanDefinitionReader加载beans.xml元数据,装配实例工厂 */
BeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);
reader.loadBeanDefinitions(new ClassPathResource("beans.xml"));
// 根据名称直接从DefaultListableBeanFactory中获取Bean实例
T bean = (T) factory.getBean("beanName");
  1. 通过ApplicationContext间接实例化内部的DefaultListableBeanFactory。
// 实例化ApplicationContext时自动构建内部的DefaultListableBeanFactory,
// 通过DefaultListableBeanFactory自动加载beans.xml元数据,装配实例工厂。
ApplicationContext context = new ClassPathXmlApplicationContext("classpath*:beans.xml ");
// 根据名称间接从内部DefaultListableBeanFactory中获取Bean实例
T bean = (T) context.getBean(beanName);

对比ApplicationContext

  如上代码所示,直接实例化DefaultListableBeanFactory时需要显示通过BeanDefinitionReader的loadBeanDefinitions方法来完成加载和装配任务。通过ApplicationContext间接实例化时,DefaultListableBeanFactory会被定义成ApplicationContext内部所依赖的容器实例自动进行加载和装配任务,此过程无需人工介入(体现在refresh上下文环境时,ApplicationContext实例会通过间接父类AbstractRefreshableApplicationContext的refreshBeanFactory方法来完成,如下代码所示),因此相对于直接实例化,间接实例化的方式显得更为简洁。

public abstract class AbstractRefreshableApplicationContext extends AbstractApplicationContext{

	protected final void refreshBeanFactory() throws BeansException {
		……
		try {
			// 构建DefaultListableBeanFactory
			DefaultListableBeanFactory beanFactory = createBeanFactory();
			beanFactory.setSerializationId(getId());
			customizeBeanFactory(beanFactory);
			// AbstractXmlApplicationContext#loadBeanDefinitions
			// 加载元数据装配DefaultListableBeanFactory
			loadBeanDefinitions(beanFactory);
			synchronized (this.beanFactoryMonitor) {
				this.beanFactory = beanFactory;
			}
		}
		……
	}
}

  更多对比如下表所示。

对比项 DefaultListableBeanFactory ApplicationContext
结构关系

基础IOC容器接口BeanFactory的默认实现类。

1.高级IOC容器接口,间接继承于BeanFactory;
2.DefaultListableBeanFactory是ApplicationContext实例内部依赖的容器。

基本功能

1.加载元数据,解析、编组和注册Bean实例的装配信息;
2.生产Bean实例,维护Bean实例的生命周期和实例间的依赖关系等。

1.具备DefaultListableBeanFactory的基本功能;
2.提供资源加载、国际化和事件发布等功能。

生产策略

延迟生产,请求方主动调用getBean方法首次获取某个单例Bean实例时,容器才会生产这个Bean实例。

全量生产,容器启动时自动生产所有单例Bean实例。

启动速度

启动时默认不生产Bean实例,启动速度快。

启动时默认生产所有单例Bean实例,启动速度较慢。

你可能感兴趣的:(Spring,#,Spring-IOC)