spring容器的实现从根源上来看的话是通过BeanFactory实现的,但是BeanFactory只是一个接口类,真正作为一个可以独立使用的容器还是通过DeafultListableBeanFactory实现的,Spring中XML文件的解析的核心类XmlBeanFactory就是继承了DefaultListableBeanFactory的子类,是Spring注册以及加载bean的默认实现,接下来我们来进一步分析一下DefaultListableBeanFactory。
1. DefaultListableBeanFactory的作用:
默认实现了ListableBeanFactory和BeanDefinitionRegistry接口,基于BeanDefinition对象,是一个成熟的bean Factroy。
Spring容器加载时,最常见的应用是:在访问bean前,需要注册所有的definition(可能从bean definition配置文件中)。使用预先建立的bean定义元数据对象,从本地的BeanDefinition表中查询BeanDefinition因而将不会花费太多成本。
DefaultListableBeanFactory既可以作为一个单独的beanFactory,也可以作为自定义beanFactory的父类。
2.DeafultListableBeanFactory所实现的接口及接口作用:
AliasRegistry:AliasRegistry是制定别名的管理规则,定义了对alias的简单的简单增改删等操作。
SimpleAlliasRegistry:主要是用map作为alias的缓存,并对接口AliasRegistry进行实现。
SingletonBeanRegistry:定义对单例的注册及获取。
BeanFactory:定义获取bean及bean的各种属性
DefaultSingletonBeanRegistry:对接口SingletonBeanRegistry各函数的实现。
HierarchicalBeanFactory:继承BeanFactory,也就是在BeanFactory的基础上定义了对parentFactory的支持。
BeanDefinitionRegistry:定义对BeanDefinition的各种增改删操作。BeanDefinition中定义的属性有诸如类名、sccope、属性、构造函数参数列表、依赖的bean、是否单例类、是否懒加载等,其实就是将Bean的定义信息存储到这个BeanDefinition相应的属性中,之后对Bean的操作就是直接对BeanDefinition进行的。
FactoryBeanRegistrySupport:在DefaultSingletonBeanRegistry基础上增加了对FactoryBean的特殊处理功能。
ConfigurableBeanFactory:提供配置Factory的各种方法。
ListableBeanFactory:根据各种条件获得bean的配置清单。
AbstractBeanFactory:综合FactoryBeanRegistrySupport和ConfigurableBeanFactory的功能。
AutowireCapableBeanFactory:提供创建bean自动注入,初始化以及应用bean的后置处理器
AbstractAutowireCapableBeanFactory:综合AbstractBeanFactory并对接口Autowire,CapableBeanFactory进行实现。
ConfigurableListableBeanFactory:BeanFactory配置清单,指定忽略类型及接口等。
而我们的核心类DefaultListableBeanFactory就是综合了上面所有的功能,主要负责了Bean注册后的处理。
层次结构
DefaultListableBeanFactory继承了AbstractAutowireCapalbeBeanFactory以及实现了BeanDefinitionRegistry,ConfigurableListableBeanFactory接口,是Spring注册及加载bean的默认实现。
3.DefaultListableBeanFactory一些常用方法:
public Object doResolveDependency(DependencyDescriptor descriptor, String beanName,
Set
private String[] doGetBeanNamesForType(ResolvableType type, boolean includeNonSingletons,
boolean allowEagerInit)
在Spring中,凡是以do开头的方法一般都是细节上的逻辑处理,也就是具体的实现代码。
关于doResolveDependency实现的具体逻辑
a.首先将 beanName 和 requiredType 作为参数,并尝试从 BeanFactory 中获取与此对于的 bean。若获取成功,就可以提前结束 doResolveDependency 的逻辑。
b.处理 @value 注解
c.解析数组、List、Map 等类型的依赖,如果解析结果不为空,则返回结果
d.根据类型查找合适的候选项
e.如果候选项的数量为0,则抛出异常。为1,直接从候选列表中取出即可。若候选项数量 > 1,则在多个候选项中确定最优候选项,若无法确定则抛出异常
f.若候选项是 Class 类型,表明候选项还没实例化,此时通过 BeanFactory.getBean 方法对其进行实例化。若候选项是非 Class 类型,则表明已经完成了实例化,此时直接返回即可。