本文主要介绍BeanFactory以及它的各种继承层级的接口、抽象类及实现类,因为内容很多,所以这里不介绍ApplicationContext继承体系下的类(虽然ApplicationContext本质上也是BeanFactory,但是毕竟这这是我们平时接触最多的两种类别,所以分开说)。
关于ApplicationContext继承体系结构在《Spring IOC-ApplicationContext的继承体系结构》一文分享说明。
BeanFactory其实就是Spring的IOC容器,当然了Spring为我们准备了许多种IOC容器来使用,这样可以方便我们从不同的层面,不同的资源位置,不同的形式的定义信息来建立我们需要的IoC容器。
在鄙人博客的不同的博文中其实都提到了Spring的一个设计理念,就是接口-抽象类-实现类的体系结构,这里多说几句为什么这么设计,熟悉设计模式的人都知道,这样的目的是为了提高软件的可维护性、可扩展性、强复用性。说的文雅一点就是使代码满足“对修改关闭、对扩展开放”、“里氏代换”原则 、“依赖倒转”原则、“接口隔离”原则、“合成\聚合复用”原则。如果项了解这几个原则可以百度下,这里不详细介绍。
废话不多说,直接上代码来看下BeanFactory的继承道理多屌。
先贴张图,大家大致看下知道下面介绍的类大概在继承体系的哪个位置。

首先看BeanFactory接口中定义的方法:

public interface BeanFactory {//这里是对FactoryBean的转义定义,因为如果使用bean的名字检索FactoryBean得到的对象是工厂生成的对象String FACTORY_BEAN_PREFIX = "&";//这里根据bean的名字,在IOC容器中得到bean实例,这个IOC容器就是一个大的抽象工厂。 Object getBean(String name) throws BeansException;//这里根据bean的名字和Class类型来得到bean实例,和上面的方法不同在于它会抛出异常:如果根据名字取得的bean实例的Class类型和需要的不同的话。<T> T getBean(String name, Class<T> requiredType);<T> T getBean(Class<T> requiredType) throws BeansException;Object getBean(String name, Object... args) throws BeansException;//这里提供对bean的检索,看看是否在IOC容器有这个名字的beanboolean containsBean(String name);//这里根据bean名字得到bean实例,并同时判断这个bean是不是单件 boolean isSingleton(String name) throws NoSuchBeanDefinitionException;//这里根据bean名字得到bean实例,并同时判断这个bean是不是原型 boolean isPrototype(String name) throws NoSuchBeanDefinitionException;//这里对得到bean实例的Class类型  Class<?> getType(String name) throws NoSuchBeanDefinitionException;//这里得到bean的别名,如果根据别名检索,那么其原名也会被检索出来  String[] getAliases(String name);

然后在看BeanFactory 的直接继承接口(二级接口),有HierarchicalBeanFactory、AutowireCapableBeanFactory和ListableBeanFactory看这三个类代码:

HierarchicalBeanFactory
作用:是为了实现bean工厂的层级关系提供支持,其中声明两个方法:

//得到父工厂
BeanFactory getParentBeanFactory();
//在本地工厂中有没有给定名称的bean,不包括继承的工厂
boolean containsLocalBean(String name);

AutowireCapableBeanFactory
作用:提供自动装配bean能力的功能支持,声明方法如下:(这个接口中所有声明的方法都是在默认的实现实在AbstractAutowireCapableBeanFactory类中默认实现)

//用个给定的class类型制造一个完整的bean
<T> T createBean(Class<T> beanClass) throws BeansException;
//bean初始化完成之后执行回调函数和后处理器,
void autowireBean(Object existingBean) throws BeansException;
// 自动注入和设置bean的属性、执行factory回调函数比如setBeanName和setBeanFactory和执行bean的所有的后处理器
Object configureBean(Object existingBean, String beanName) throws BeansException;
//调用bean的init方法,这个方法是客户配置的,在bean实例化之后调用
Object initializeBean(Object existingBean, String beanName) throws BeansException;
//初始化完成之后应用后处理器
Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
//应用前处理器
Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName);

ListableBeanFactory
作用:可以枚举所有的bean实例,是为了使客户端访问工厂中的bean而设计的,主要方法(这些方法顾名思义,所有的方法实现在StaticListableBeanFactory、AbstractApplicationContext和DefaultListableBeanFactory中):

//是否含有给定的名称的bean
boolean containsBeanDefinition(String beanName);
int getBeanDefinitionCount();
//得到工厂所有的bean的名称数组
String[] getBeanDefinitionNames();
String[] getBeanNamesForType(Class<?> type);
//根据给定的类型得到和相应的策略得到所有的bean名称数组
String[] getBeanNamesForType(Class<?> type, boolean includeNonSingletons, boolean allowEagerInit);
//根据给定过的类型得到所有该类型的bean,返回的结果是一个Map<bean名称,bean对象>的形式
<T> Map<String, T> getBeansOfType(Class<T> type) throws BeansException;
//得到给定名称的bean上的给定注解类型的注解对象
<A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType);

下面我们介绍BeanFactory 的三级接口,看继承关系图知道是ConfigurableBeanFactory和ConfigurableListableBeanFactory。

ConfigurableBeanFactory
作用: 实现可配置的bean的环境功能,这个接口继承自HierarchicalBeanFactory所以支持层级关系的工厂,和SingletonBeanRegistry所以肯定支持单例工厂行为,看主要方法代码(在AbstractBeanFactory类中默认实现):

void setConversionService(ConversionService conversionService);
void setTypeConverter(TypeConverter typeConverter);
//支持自定义bean的作用范围,可以理解为单例和多例之外的
void registerScope(String scopeName, Scope scope);
//归并的将给定的name的bean的定义
BeanDefinition getMergedBeanDefinition(String beanName);
//添加处理器
void addBeanPostProcessor(BeanPostProcessor beanPostProcessor);
//下面是3个destory方法
void destroyBean(String beanName, Object beanInstance);
void destroyScopedBean(String beanName);
//只能销毁所有单例的bean,因为多例的是不归Spring控制的,是由客户端控制的
void destroySingletons();

ConfigurableListableBeanFactory
作用:提供可配置的、可访问的功能,接口中的方法在在DefaultListableBeanFactory默认实现默认实现。

public interface ConfigurableListableBeanFactoryextends ListableBeanFactory, AutowireCapableBeanFactory, ConfigurableBeanFactory {//冻住之后bean定义就不能在被修改和进行任何的后处理器规定的操作void freezeConfiguration();//确保所有的单例bean都实例化void preInstantiateSingletons() throws BeansException;//BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;//判断当前的bean是不是作为其它bean的依赖注入的boolean isAutowireCandidate(String beanName, DependencyDescriptor descriptor);

上面是接口的继承体系和说明,下面来介绍接口下抽象类的代码,在上面的介绍中我们知道就两个抽象类AbstractAutowireCapableBeanFactory和AbstractBeanFactory,先看继承关系:

public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactoryimplements AutowireCapableBeanFactory {
public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory {

可以知道AbstractAutowireCapableBeanFactory 是AbstractBeanFactory 类的子类。通过上面的接口和抽象类的介绍我们将研究的重点转到转到这两个抽象类中。
这里我们主要看bean工厂是怎么将xml中的定义信息转换为互相依赖的bean定义或者初始化为实体对象。
先看在继承体系偏上的类AbstractBeanFactory ,这个类最重要的是对BeanFactory中getBean()的实现,直接看实现的代码:

………………
public <T> T getBean(String name, Class<T> requiredType, Object... args) throws BeansException {return doGetBean(name, requiredType, args, false);
}

在看doGetBean()方法代码:

………………
//首先从单例工厂得到有没有
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
//不是但单例的
else {//看是不是在父BeanFactory ,因为实现了HierarchicalBeanFactory接口BeanFactory parentBeanFactory = getParentBeanFactory();if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {return parentBeanFactory.getBean(nameToLookup, requiredType);}
……………………if (mbd.isSingleton()) {//单例的//用回调的形式建造bean并且放入单例工厂sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {public Object getObject() throws BeansException {try {return createBean(beanName, mbd, args);}……………………//多例的else if (mbd.isPrototype()) {Object prototypeInstance = null;beforePrototypeCreation(beanName);prototypeInstance = createBean(beanName, mbd, args);………………else {//没有明确是单例的还是不是,有自己的作用域scopeString scopeName = mbd.getScope();final Scope scope = this.scopes.get(scopeName);Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() {public Object getObject() throws BeansException {               return createBean(beanName, mbd, args);……………………

可以上面是分为三种情况得到bean的,单例的、多例的、Scope的。但是所有的情况最终都定位到一个方法——createBean(beanName, mbd, args),这个方法在AbstractBeanFactory 是抽象的protected abstract Object createBean(,很明显,只能在子类中实现,自然就要看AbstractAutowireCapableBeanFactory 中的建造bean的createBean()代码:

protected Object createBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)throws BeanCreationException {………………//如果没有找到这个name的class类型是会抛出异常的resolveBeanClass(mbd, beanName);//判断在xml中定义的overrides方法存在mbd.prepareMethodOverrides();………………//用bean的前处理器去实例化Object bean = resolveBeforeInstantiation(beanName, mbd);………………Object beanInstance = doCreateBean(beanName, mbd, args);………………

好的,代码定位到**doCreateBean(beanName, mbd, args)**方法:

//逐渐的构造一个bean,分别用factory method, and autowiring a constructor.去构造,这些都是在xml中配置的。
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) {………………instanceWrapper = createBeanInstance(beanName, mbd, args);………………//构造bean并且注入依赖所有bean的属性值Object exposedObject = bean;try {populateBean(beanName, mbd, instanceWrapper);if (exposedObject != null) {//调用配置的init方法exposedObject = initializeBean(beanName,     exposedObject, mbd);} }

代码定位到createBeanInstance(beanName, mbd, args)

//用 factory method, constructor autowiring, or simple instantiation.三种方法去实例化一个bean
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {………………//用getFactoryMethodName去实例化一个if (mbd.getFactoryMethodName() != null)  {return instantiateUsingFactoryMethod(beanName, mbd, args);}………………//用构造函数if (autowireNecessary) {return autowireConstructor(beanName, mbd, null, null);}else {//用默认的构造函数得到return instantiateBean(beanName, mbd);}………………
}

再定位代码到populateBean(beanName, mbd, instanceWrapper):

//主要是bean中的成员变量的初始化和注入,《依赖的注入》
protected void populateBean(String beanName, AbstractBeanDefinition mbd, BeanWrapper bw) {……………………if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||     mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) { MutablePropertyValues newPvs = new MutablePropertyValues(pvs);              // Add property values based on autowire by name if applicable.             if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) { autowireByName(beanName, mbd, bw, newPvs);                              }                                                                           // Add property values based on autowire by type if applicable.             if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) { autowireByType(beanName, mbd, bw, newPvs);                              }                                                                           pvs = newPvs;
}                                                                               ……………………//将属性的引用和具体的对象结合起来,用到了java的反射机制applyPropertyValues(beanName, mbd, bw, pvs);
}

最后是applyPropertyValues(beanName, mbd, bw, pvs)

protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {try {//调用BeanWrapper类的方法bw.setPropertyValues(new MutablePropertyValues(deepCopy));}

这里补充一下BeanWrapperImpl类中设置属性依赖的代码实现:

………………
//如果有key属性配置,证明是array  list  或者map
if (tokens.keys != null) {if (propValue.getClass().isArray()) {else if (propValue instanceof List) {else if (propValue instanceof Map) {}
//普通的属性设置
else{………………writeMethod.setAccessible(true);writeMethod.invoke(object, value);
}
………………

至此bean的如何初始化和如何进行依赖注入就已经研究代码完毕。
下面也是最后我们看一下这个继承体系中具体类XmlBeanFactory、DefaultListableBeanFactory的实现代码:
XmlBeanFactory

//这个类的实现很简单,只是委托XmlBeanDefinitionReader进行xml的读取和配置信息的加载
public class XmlBeanFactory extends DefaultListableBeanFactory {private final XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(this);// 构造的时候就进行xml文件的解析public XmlBeanFactory(Resource resource, BeanFactory parentBeanFactory) throws BeansException {super(parentBeanFactory);this.reader.loadBeanDefinitions(resource);}
}

关于XmlBeanFactory加载xml,会在Spring IOC-XmlBeanFactory如何加载xml及如何存储转换后的信息一文介绍。

DefaultListableBeanFactory
是XmlBeanFactory的父类,也就是而你看下文章最前面的继承图,你会发现DefaultListableBeanFactory拥有这个继承体系中的所有功能。
那么除了继承父类的功能方法外,它独特的功能在于对ConfigurableListableBeanFactory和ListableBeanFactory接口的实现。

Spring IOC-BeanFactory的继承体系结构相关推荐

  1. Spring IoC(一)IoC容器的设计与实现:BeanFactory与ApplicationContext

    在写BeanFactory与ApplicationContext 之前,我想先简单聊一聊Spring IoC 容器,希望能给大家一个参考.如果你对这反面的知识比较了解,可以直接跳过. (一)Sprin ...

  2. SSM 整合 4:Spring IoC 容器基于的两个重要接口 BeanFactory 和 ApplicationContext

    文章目录 前言 一.BeanFactory 接口 1.1.加载 Spring 配置文件创建 BeanFactory 接口实例 1.2.开发中的运用以及使用说明 二.ApplicationContext ...

  3. Spring:源码解读Spring IOC原理

    2019独角兽企业重金招聘Python工程师标准>>> 一.什么是Ioc/DI? IOC容器:主要是完成了 完成对象的创建和依赖的管理注入等. 先从我们自己设计这样一个视角来考虑: ...

  4. Spring IOC核心原理分析

    学习过Spring框架的人一定都会听过Spring的IoC(控制反转) .DI(依赖注入)这两个概念,对于初学Spring的人来说,总觉得IoC .DI这两个概念是模糊不清的,是很难理解的,本文系统分 ...

  5. Spring IOC 学习总结

    1 什么是IOC.DI IoC-Inversion of Control,即"控制反转",不是什么技术,而是一种设计思想.在Java开发中,Ioc意味着将你设计好的对象交给容器控制 ...

  6. Spring IoC是什么

    IoC是什么 Ioc-Inversion of Control,即"控制反转",不是什么技术,而是一种设计思想.在Java开发中,Ioc意味着将你设计好的对象交给容器控制,而不是传 ...

  7. 面试官:你来说一下Spring IOC容器的创建过程

    这篇文章主要讲解 IOC 容器的创建过程,让你对整体有一个全局的认识,文章没有复杂嵌套的 debug 流程,相对来说比较简单. 不 BB,上文章目录. 1. 基础知识 1.1 什么是 Spring I ...

  8. Spring IOC和Bean生命周期以及源码分析

    这篇文章主要讲解 IOC 容器的创建过程,让大家对整体有一个全局的认识,文章目录如图: 1. 基础知识 1.1 什么是 Spring IOC ? IOC 不是一种技术,只是一种思想,一个重要的面向对象 ...

  9. 源码深度解析之 Spring IOC

    这篇文章主要讲解 IOC 容器的创建过程,让你对整体有一个全局的认识,文章没有复杂嵌套的 debug 流程,相对来说比较简单. 不 BB,上文章目录. 1. 基础知识 1.1 什么是 Spring I ...

最新文章

  1. 深度学习崛起十年:“开挂”的OpenAI革新者
  2. visio网络拓扑图模具_【无机纳米材料科研制图——Visio 0304】上转换NaYF4:Yb Er/Tm光子能级跃迁图...
  3. javac环境变量配置(转)
  4. javaioIOException - Cannot run program javac error 2 No such file or direct
  5. Collections 工具类常见方法
  6. Spring :@Configuration 注解
  7. java oracle分页查询语句_oracle分页查询语句,java得到分页查询语句的方法
  8. Missing required icon file.Thebundle does not con
  9. 怎么在html mui中找到下拉刷新,HelloMUI例子中的下拉刷新
  10. 修改CentOS 7默认语言为中文
  11. linux 文件同步脚本,Linux rsync同步文件脚本
  12. 获取应用名字、版本号
  13. 上课解除教师机控制(红蜘蛛)超详细
  14. win10(win8)上安装miniTool后出现请手动安装fastboot驱动问题
  15. Flash CS6 新功能
  16. 和小松一起聆听遥唤根本上师
  17. openGPS.cn - 高精度IP定位原理,定位误差说明
  18. 智慧农业实验室第一次成果
  19. Ubutu Mosquitto部署和相关的配置(支持websocket)
  20. Overflow during an arithmetic operation (type P) in program(数据溢出)

热门文章

  1. Linux--Sys_Read系统调用过程分析
  2. 基于stm32f429的手写识别_关注智能手机老年用户:百度输入法手写模型迎来重磅升级...
  3. css unchecked,详细介绍CSS中的伪选择器
  4. linux怎样自制库_如何制作自己的LINUX系统?
  5. windows7 下vmware workstation 12安装Ubuntu16.04虚拟机及安装和共享文件夹
  6. vue-router的hash模式和history模式,
  7. day24 01 初识继承
  8. python基础之常用的高阶函数
  9. Linux 和 Vim 常用命令整理
  10. Java中继承thread类与实现Runnable接口的区别