BeanFactory体系结构
BeanFactory是Spring中非常重要的一个类,搞懂了它,你就知道了bean的初始化和摧毁过程,对于深入理解IOC有很大的帮助。
BeanFactory体系结构
首先看一下使用IDEA生成的继承层次图(图中去掉了ApplicationContext的继承图):

可以看到BeanFactory下的接口主要分为三个:
HierarchicalBeanFactory:详细的分析见https://www.cnblogs.com/zhangfengxian/p/11086695.html#hierarchicalbeanfactoryListableBeanFactory:详细的分析见https://www.cnblogs.com/zhangfengxian/p/11086695.html#listablebeanfactoryAutowireCapableBeanFactory:能够自动装配的bean的工厂需要实现此接口,下面会进行详细的说明。
关于BeanFactory的分析见https://www.cnblogs.com/zhangfengxian/p/11086695.html#beanfactory
BeanFactory接口分析
下面将对BeanFactory中的接口进行分析。
AutowireCapableBeanFactory
该接口提供了对现有bean进行自动装配的能力,设计目的不是为了用于一般的应用代码中,对于一般的应用代码应该使用BeanFactory和ListableBeanFactory。其他框架的代码集成可以利用这个接口去装配和填充现有的bean的实例,但是Spring不会控制这些现有bean的生命周期。你也许注意到了ApplicationContext中的getAutowireCapableBeanFactory()能获取到AutowireCapableBeanFactory的实例(https://www.cnblogs.com/zhangfengxian/p/11086695.html#applicationcontext设计解析)。同样,也能实现BeanFactoryAware接口来接收BeanFactory(应用程序上下暴露的内部使用的BeanFactory)的实例,然后将其转换成AutowireCapableBeanFactory。
下面看一下这个接口中的静态成员变量和方法:
// 定义了bean的装配策略
int AUTOWIRE_NO = 0; // 不进行装配
int AUTOWIRE_BY_NAME = 1; // 根据名字进行装配
int AUTOWIRE_BY_TYPE = 2; // 根据类型进行装配
int AUTOWIRE_CONSTRUCTOR = 3; // 根据构造函数进行装配
@Deprecated
int AUTOWIRE_AUTODETECT = 4; // Spring3.0已经过时的方法,通过省视bean来决定适当的装载策略
//Spring5.1后增加,原始实例的后缀,例如"com.mypackage.MyClass.ORIGINAL",强制返回给定的实例(没有代理)
String ORIGINAL_INSTANCE_SUFFIX = ".ORIGINAL";
// 完全创建给定类的一个新的实例,包括所有适用的BeanPostProcessor
// 填充注解的field和方法,并且会应用所有的初始化回调函数
<T> T createBean(Class<T> beanClass) throws BeansException;
// 装配bean,通过应用初始化之后的回调函数和bean属性的后置处理来填充给定的bean的实例
// 本质上是为了在创建新的实例或者反序列化实例时,填充(重新填充)实例中注解的field和方法
void autowireBean(Object existingBean) throws BeansException;
// 配置给定的原始bean:自动装配bean的属性,应用bean的属性值、工厂回调函数(例如setBeanName,values)
// 同样也会应用所有bean的后置处理器
Object configureBean(Object existingBean, String beanName) throws BeansException;
// 使用指定的装配策略来完全创建一个新的bean的实例
Object createBean(Class<?> beanClass, int autowireMode, boolean dependencyCheck) throws BeansException;
// 使用指定的装配策略来实例化一个给定类新的bean的实例
// 不会应用标准的BeanPostProcessor回调函数或者在未来执行任何bean的初始化
Object autowire(Class<?> beanClass, int autowireMode, boolean dependencyCheck) throws BeansException;
// 根据名字和类型来自动装配给定bean的实例的属性
// 不会应用标准的BeanPostProcessor回调函数或者在未来执行任何bean的初始化
void autowireBeanProperties(Object existingBean, int autowireMode, boolean dependencyCheck)
throws BeansException;
// 应用给定名字的bean的定义的属性值到给定的bean的实例
// 该方法不会自动装配bean属性,仅仅应用明确定义的属性值
void applyBeanPropertyValues(Object existingBean, String beanName) throws BeansException;
// 初始化给定的原始的bean应用bean的属性值、工厂回调函数(例如setBeanName,values)
// 同样也会应用所有bean的后置处理器
Object initializeBean(Object existingBean, String beanName) throws BeansException;
// 应用BeanPostProcessor到给定的现存的bean的实例,调用postProcessBeforeInitialization方法
Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException;
// 应用BeanPostProcessor到给定的现存的bean的实例,postProcessAfterInitialization
Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException;
// 摧毁给定的bean的实例,应用DisposableBean规约和注册的DestructionAwareBeanPostProcessor
void destroyBean(Object existingBean);
// 解析唯一匹配给定对象类型的bean的实例,该方法是getBean(Class)的变种,只不过它还提供了匹配实例的bean的名字
<T> NamedBeanHolder<T> resolveNamedBean(Class<T> requiredType) throws BeansException;
// 解析给定bean的名字的实例,提供了用于暴露目标的工厂方法的依赖描述符
Object resolveBeanByName(String name, DependencyDescriptor descriptor) throws BeansException;
// 针对在工厂中定义的bean来解析指定的依赖
Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName) throws BeansException;
// 针对在工厂中定义的bean来解析指定的依赖
Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException;
ConfigurableBeanFactory
ConfigurableBeanFactory提供了bean工厂的配置机制(除了BeanFactory接口中的bean的工厂的客户端方法)。该BeanFactory接口不适应一般的应用代码中,应该使用BeanFactory和ListableBeanFactory。该扩展接口仅仅用于内部框架的使用,并且是对bean工厂配置方法的特殊访问。
ConfigurableBeanFactory继承自HierarchicalBeanFactory和SingletonBeanRegistry,下面先看下SingletonBeanRegistry:
SingletonBeanRegistry是为了共享的bean的实例而定义的注册器,以统一的方式暴露单例管理机制。下面是在此接口中定义的方法:
// 在bean的注册器中以给定的bean的名字将给定的现存对象注册为单例
void registerSingleton(String beanName, Object singletonObject);
// 根据给定的bean的名字来获取单例bean,可能为null
Object getSingleton(String beanName);
// 是否包含给定名字的单例bean
boolean containsSingleton(String beanName);
// 获取所有在注册器中注册的单例bean的名字
String[] getSingletonNames();
// 获取所有在注册器中注册的单例bean的数量
int getSingletonCount();
// 获取在这个注册器中使用的单例的mutex(用于外部协同)
Object getSingletonMutex();
需要注意的是使用registerSingleton方法注册的单例bean,不会执行任何的初始化回调函数(尤其不会调用InitializingBean的afterPropertiesSet方法),同样也不会接收任何的摧毁回调函数。如果需要接收初始化和摧毁回调函数,请注册bean的定义而不是现存的实例对象。
接下来看下ConfigurableBeanFactory中定义的方法:
// 作用域
String SCOPE_SINGLETON = "singleton"; // 单例作用域
String SCOPE_PROTOTYPE = "prototype"; // 原型作用域
// 设置父级bean工厂
void setParentBeanFactory(BeanFactory parentBeanFactory) throws IllegalStateException;
// 设置bean的类加载器,默认为线程上下文类加载器
void setBeanClassLoader(@Nullable ClassLoader beanClassLoader);
// 获取bean的类加载器
@Nullable
ClassLoader getBeanClassLoader();
// 设置临时的类加载器
void setTempClassLoader(@Nullable ClassLoader tempClassLoader);
// 获取临时的类加载器
@Nullable
ClassLoader getTempClassLoader();
// 设置是否缓存bean的元数据
void setCacheBeanMetadata(boolean cacheBeanMetadata);
// 是否缓存bean的元数据
boolean isCacheBeanMetadata();
// 设置bean的表达式解析器,以统一的EL兼容样式支持#{...}这样的表达式
void setBeanExpressionResolver(@Nullable BeanExpressionResolver resolver);
// 获取bean的表达式解析器
@Nullable
BeanExpressionResolver getBeanExpressionResolver();
// 设置转换服务,用于转换属性值
void setConversionService(@Nullable ConversionService conversionService);
// 获取转换服务
@Nullable
ConversionService getConversionService();
// 添加属性编辑器注册者
void addPropertyEditorRegistrar(PropertyEditorRegistrar registrar);
// 为所有给定的属性注册自定义属性编辑器
void registerCustomEditor(Class<?> requiredType, Class<? extends PropertyEditor> propertyEditorClass);
// 使用在BeanFactory中注册的自定义编辑器来初始哈给定的属性编辑器注册者
void copyRegisteredEditorsTo(PropertyEditorRegistry registry);
// 设置类型转换器
void setTypeConverter(TypeConverter typeConverter);
// 获取类型转换器
TypeConverter getTypeConverter();
// 添加嵌入值解析器,例如注册属性
void addEmbeddedValueResolver(StringValueResolver valueResolver);
// 在BeanFactory是否有注册嵌入值解析器
boolean hasEmbeddedValueResolver();
// 解析给定的嵌入的值
@Nullable
String resolveEmbeddedValue(String value);
// 添加bean的后置处理器
void addBeanPostProcessor(BeanPostProcessor beanPostProcessor);
// 获取bean的后置处理器个数
int getBeanPostProcessorCount();
// 注册作用域
void registerScope(String scopeName, Scope scope);
// 获取注册的作用域的名字
String[] getRegisteredScopeNames();
// 获取作用域
@Nullable
Scope getRegisteredScope(String scopeName);
// 提供一个与这个工厂有关的安全访问控制上下文
AccessControlContext getAccessControlContext();
// 从给定的其他的工厂拷贝所有相关的配置。不应该包含任何bean的定义元数据
void copyConfigurationFrom(ConfigurableBeanFactory otherFactory);
// 注册别名
void registerAlias(String beanName, String alias) throws BeanDefinitionStoreException;
// 解析所有别名的目标名称和在工厂中注册的别名,将给定的StringValueResolver应用于它们
void resolveAliases(StringValueResolver valueResolver);
// 获取合并的bean的定义
BeanDefinition getMergedBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
// 给定名字的bean是否为FactoryBean
boolean isFactoryBean(String name) throws NoSuchBeanDefinitionException;
// 显式的设置指定bean的目前在创建状态
void setCurrentlyInCreation(String beanName, boolean inCreation);
// 指定的bean目前是否为在建状态
boolean isCurrentlyInCreation(String beanName);
// 注册给定bean所依赖的bean
void registerDependentBean(String beanName, String dependentBeanName);
// 获取所有依赖于指定bean的bean的名字
String[] getDependentBeans(String beanName);
// 获取所有指定bean所依赖的bean的名字
String[] getDependenciesForBean(String beanName);
// 根据bean的定义来摧毁给定的bean的实例(通常是从工厂中获取到的原型实例)
void destroyBean(String beanName, Object beanInstance);
// 在当前目标作用域中摧毁指定的作用域中的bean
void destroyScopedBean(String beanName);
// 摧毁在工厂中的所有单例bean
void destroySingletons();
上面的大部分方法都是获取或者设置一些配置的信息,以便协同来完成BeanFactory的配置。
ConfigurableListableBeanFactory
ConfigurableListableBeanFactory接口继承自ListableBeanFactory, AutowireCapableBeanFactory, ConfigurableBeanFactory。大多数具有列出能力的bean工厂都应该实现此接口。此了这些接口的能力之外,该接口还提供了分析、修改bean的定义和单例的预先实例化的机制。这个接口不应该用于一般的客户端代码中,应该仅仅提供给内部框架使用。下面是这个接口的方法:
// 忽略用于自动装配的依赖的类型
void ignoreDependencyType(Class<?> type);
// 忽略用于自动装配的依赖的接口
void ignoreDependencyInterface(Class<?> ifc);
// 给特定的依赖类型注册自动装配的值
void registerResolvableDependency(Class<?> dependencyType, @Nullable Object autowiredValue);
// 指定的bean是否为自动装配的候选者
boolean isAutowireCandidate(String beanName, DependencyDescriptor descriptor)
throws NoSuchBeanDefinitionException;
// 获取bean的定义
BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
// 获取这个工厂中的所有bean的名字的迭代器
Iterator<String> getBeanNamesIterator();
// 清除元数据缓存
void clearMetadataCache();
// 冻结所有bean的定义
void freezeConfiguration();
// 工厂中bean的定义是否冻结了
boolean isConfigurationFrozen();
// 对非懒加载的单例进行预先初始化
void preInstantiateSingletons() throws BeansException;
AbstractBeanFactory
AbstractBeanFactory继承自FactoryBeanRegistrySupport,实现了ConfigurableBeanFactory接口。AbstractBeanFactory是BeanFactory的抽象基础类实现,提供了完整的ConfigurableBeanFactory的能力。在这里不讨论该抽象类的实现细节,只要知道这个类是干什么的就行了,会面会有更加详细的章节来讨论。
- 单例缓存
- 别名的管理
- FactoryBean的处理
- 用于子bean定义的bean的合并
- bean的摧毁接口
- 自定义的摧毁方法
- BeanFactory的继承管理
子类需要实现的模板方法如下:
// 是否包含给定名字的bean的定义
protected abstract boolean containsBeanDefinition(String beanName);
// 根据bean的名字来获取bean的定义,子类通常要实现缓存
protected abstract BeanDefinition getBeanDefinition(String beanName) throws BeansException;
// 为给定的已经合并了的bean的定义创建bean的实例
protected abstract Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException;
AbstractAutowireCapableBeanFactory
AbstractAutowireCapableBeanFactory继承自AbstractBeanFactory,实现了AutowireCapableBeanFactory接口。该抽象了实现了默认的bean的创建。
- 提供了bean的创建、属性填充、装配和初始化
- 处理运行时bean的引用,解析管理的集合、调用初始化方法等
- 支持构造器自动装配,根据类型来对属性进行装配,根据名字来对属性进行装配
子类需要自行实现的模板方法如下:
// 用于根据类型来进行自动装配
Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException;
DefaultListableBeanFactory
DefaultListableBeanFactory继承自AbstractAutowireCapableBeanFactory,实现了ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable接口。这个类是一个非常完全的BeanFactory,基于bean的定义元数据,通过后置处理器来提供可扩展性。
XmlBeanFactory
XmlBeanFactory继承自DefaultListableBeanFactory,用来从XML文档中读取bean的定义的一个非常方便的类。最底层是委派给XmlBeanDefinitionReader,实际上等价于带有XmlBeanDefinitionReader的DefaultListableBeanFactory。
思维导图

BeanFactory体系结构的更多相关文章
- Spring源码学习之BeanFactory体系结构
一.BeanFactory BeanFactory是Spring IOC容器的鼻祖,是IOC容器的基础接口,所有的容器都是从它这里继承实现而来.可见其地位.BeanFactory提供了最基本的IOC容 ...
- Spring的BeanFactory体系结构(一)
本文使用的代码是: Spring 3.0 接 触Spring也有很长一段时间了.但是,每次都是直接使用Spring直接提供的API,时间久了,自然也会想探索Spring里面的奥秘.今天上 午,整理出了 ...
- Spring BeanFactory源码学习
一.BeanFactory BeanFactory是Spring IOC容器的基础,是IOC容器的基础接口,所有的容器都是从它这里继承实现而来.BeanFactory提供了最基本的IOC容器的功能,即 ...
- Spring的BeanFactory是什么?
什么是BeanFactory? 提到Spring,总是让人第一时间想起IOC容器,而IOC容器的顶层核心接口就是我们的BeanFactory,如果能够理解BeanFactory的体系结构想必能让我们对 ...
- Spring源码阅读-BeanFactory体系结构分析
BeanFactory是Spring中非常重要的一个类,搞懂了它,你就知道了bean的初始化和摧毁过程,对于深入理解IOC有很大的帮助. BeanFactory体系结构 首先看一下使用IDEA生成的继 ...
- 一文带你解读Spring5源码解析 IOC之开启Bean的加载,以及FactoryBean和BeanFactory的区别。
前言 通过往期的文章我们已经了解了Spring对XML配置文件的解析,将分析的信息组装成BeanDefinition,并将其保存到相应的BeanDefinitionRegistry中,至此Spring ...
- Tornado
Tornado 是 FriendFeed 使用的可扩展的非阻塞式 web 服务器及其相关工具的开源版本.这个 Web 框架看起来有些像web.py 或者 Google 的 webapp,不过为了能有效 ...
- Spring源码学习之IOC实现原理(二)-ApplicationContext
一.Spring核心组件结构 总的来说Spring共有三个核心组件,分别为Core,Context,Bean.三大核心组件的协同工作主要表现在 :Bean是包装我们应用程序自定义对象Object的,O ...
- spring源码深度解析— IOC 之 开启 bean 的加载
概述 前面我们已经分析了spring对于xml配置文件的解析,将分析的信息组装成 BeanDefinition,并将其保存注册到相应的 BeanDefinitionRegistry 中.至此,Spri ...
随机推荐
- ES6_05_三点运算符和形参默认值
三点运算符的用途: # 1. rest(可变)参数 * 用来取代arguments 但比 arguments 灵活,只能是最后部分形参参数 function fun(...values) { cons ...
- 性能测试即服务-docker部署jmeter及.netcore应用
前言 现在各种业务都追求上云,通俗的讲,“XX即服务”,作为一名专职的性能测试调优人员的我,由于会点三脚猫的开发功夫,“性能测试即服务”这种开发大任就落到我头上了,先做一个能完成核心压测功能的基础版. ...
- 客户端持久化数据库---indexedDB使用
_ 阅读目录 一:什么是indexedDB数据库? 二:IndexedDB数据库操作 2.1 打开或创建数据库 2.2 创建对象仓库(或叫创建表) 2.3 创建索引 2.4 新增数据 2.5 读取数据 ...
- 给即将或刚进入it行业的朋友的参考--体育生转行到Java的经历
首先声明,不喜勿喷我这个历经千辛万苦转入Java行业的人.相信很多正在学校中迷茫和在毕业后对于现状不满意的朋友通过各种的渠道进行信息汇总,了解了软件行业的高工资和多机会,正摩拳擦掌准备在这个领域大干一 ...
- C++学习书籍推荐《Effective C++ 第三版》下载
百度云及其他网盘下载地址:点我 编辑推荐 <Effective C++:改善程序与设计的55个具体做法(第3版)(中文版)(双色)>前两个版本抓住了全世界无数程序员的目光.原因十分明显:S ...
- Java基础之回味finally
平时大家try…catch…finally语句用的不少,知道finally块一定会在try…catch..执行结束时执行,但是具体是在什么时候执行呢,今天我们一起来看下. public static ...
- GitHub代码阅读神器,你值有拥有!
(题图:from github) Github作为全球最大的程序员聚集地,已经成为学习开发技能的绝佳伴侣(如果你是程序员,但你还没有账户的话,这里建议你去signup,毕竟能增加成长的机会,不能错过 ...
- Appium+python自动化(二十一)- 让猴子按你指令大闹手机,让你成为耍猴高手 - Monkey(猴子) - MonkeyScript(超详解)
简介 一年一度的暑假如期而至,每年必不可少的,便是<西游记>这部经典电视连续剧的播出,作为一名90后,对于这部经典剧的情谊,就是观看已成为一种习惯.依然深刻的记得,小时候妈妈为了催促我睡觉 ...
- py+selenium 明明定位不到元素,但却不报错或是报错AttributeError: 'list' object has no attribute 'click'【已解决】
问题:定位不到元素,但却不报错或者出现报错AttributeError: 'list' object has no attribute 'click' 如图 或者 解决方法: 将”driver ...
- CF510C Fox And Names——拓扑排序练习
省委代码: #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> # ...