接触Spring也有很长一段时间了。但是,每次都是直接使用Spring直接提供的API,时间久了,自然也会想探索Spring里面的奥秘。今天上午,整理出了Spring的BeanFactory的一个体系结构(当然不是完整的,是以XmlFactory为最终目标),如下图(点击可到图片页面):
沿着XmlBeanFactory向上追溯,可以形成上面的BeanFactory体系结构。虽然不是很全面,但是如果这个图能理解透,我相信,Spring的BeanFactory就能理解透了。之后的系列我也会以这个图为中心,深入的去学习Spring的BeanFactory。
下面是对各个接口的理解。
BeanFactory
这个就是BeanFactory容器的最原始接口,也是spring容器提供的最原始客户端接口。
AutowireCapableBeanFactory
拥有自动装配能力的BeanFactory。这个BeanFactory并非是要用到应用中去的,在应用中要用,就用BeanFactory或者是ListableBeanFactory。这个接口更多的作用是用于和其他框架的结合,把不在Spring容器中的Bean加入到Spring容器声明周期管理中来。
需要注意的是,在Spring的ApplicationContext(Spring的应用容器)中,并没有实现这个接口,因为这个接口在应用中,确实很少用到。
不过,你可以通过ApplicationContext的getAutowireCapableBeanFactory()方法获得。或者,你也可以实现BeanFactoryAware(这个接口就是为了取得BeanFactory的),然后把BeanFactory转换成AutowireCapableBeanFactory。
HierarchicalBeanFactory
有层次的BeanFactory。如果实现了这个接口,可能就以为着你也需要实现ConfigurableBeanFactory。因为ConfigurableBeanFactory定义了设置父容器的方法,而HierarchicalBeanFactory的方法只有获得父容器的方法。而一般情况下,ConfigurableBeanFactory接口直接继承了HierarchicalBeanFactory。所以,它的实现,也是肯定要设置父容器的。
ListableBeanFactory
顾名思义,此BeanFactory是可以把容器中的bean循环枚举出来,而不是按照名字一个一个去取。
如果实现此接口的同时,也实现了HierarchicalBeanFactory,那么这个接口中的方法是不会去考虑父容器中的bean的。
需要注意的是:除了getBeanDefinitionCount和containsBeanDefinition方法之外,其他的方法最好不要直接在代码中调用,因为其实现可能会非常慢。
SingletonBeanRegistry
这个接口定义了一个注册singleton bean的容器。此接口可以被BeanFactory的实现实现,用来形成一个统一管理singleton bean的风格。ConfigurableBeanFactory接口就继承了此接口。
ConfigurableBeanFactory
此接口定义了BeanFactory的扩配置功能,几乎所有的beanFactory都会实现这个接口。
同样,此接口也不推荐在常见的应用代码中使用(还是推荐使用BeanFactory和ListableBeanFactory)。这个接口也赋予了BeanFactory可扩展的功能,
ConfigurableListableBeanFactory
又是可配置,又是Listable的BeanFactory,就可以实现这个接口。除了ConfigurableBeanFactory的功能之外,它还提供了访问和修改BeanDefinition,预实例化singletons。
AliasRegistry
管理别名的公共接口。
BeanDefinitionRegistry
注册BeanDefinition(Spring内部映射Bean的数据结构)的接口。
在这个体系中,接口部分,我就看了上面这些。下篇文章,我会深入去学习每个接口的实现,就是上图中右边的那些实现。
SimpleAliasRegistry实现的是AliasRegistry,也就是提供了别名的注册场所。
AliasRegistry是一个通用的管理别名的接口,BeanDefinitionAliasRegistry接口就是继承此接口。
此接口定义的方法(服务)也很简单:
- registerAlias 注册一个别名
- removeAlias 删除别名
- isAlias 判断是否是别名
- getAliases 获得一个名字的所有别名,以String数组的形式返回
那它的实现SimpleAliasRegistry,其内部采用了一个ConcurrentHashMap来进行别名的存储。因为方法的数量比较少,所以分别对这四个方法进行详读。
void registarAlias(String name, String alias)
首先,会看看 name 是否和 alias 相等,如果相等,就把存储器中的 alias 删除。
然后,其内部还定义了一个 allowAliasOverriding 的方法来判断是否允许覆盖。子类可以复写此方法,调整其策略。
void removeAlias(String alias)
很容易理解,但是这里需要注意,如果这个alias找不到,那么程序是会直接抛异常的,而不是默默的忽略。这个点在接口中也有提到的。
boolean isAlias(String name)
判断其是否是别名。
String[] getAliases(String name)
此方法会同步其内部的存储器,然后递归的进行查找,直到把所有的别名找出为止。
这里有个问题,为什么synchronized的对象,是这个内部的存储器呢?
经过一系列的研究,终于了解。原来,内部的存储器,是一个ConcurrentHashMap,而对这个存储器进行上锁,可以有效的防止在获取别名是,其他线程对存储器的修改。
接着学习 DefaultSingletonBeanRegistry。
一听名字,就知道这是一个SingletonBean注册的地方,此类也实现了SingletonBeanRegistry接口,继承了SimpleAliasRegistry。这也可以理解,DefaultSingletonBeanRegistry既有管理SingletonBean的功能,又提供了别名的功能,那当然可以继承SimpleAliasRegistry了。
DefaultSingletonBeanRegistry是一个通用的存储共享bean实例的地方,通过bean的名字获得bean。同时,它也给提供一次性bean的注册功能。
这个类的主要作用是,给BeanFactory的实现,提供基本的管理 singleton bean 实例功能。
这个类中,使用了三个主要的存储器(map)来分别存储 singletonObject,singletonFactory,earlySingletonObject。
当注册一个 singleton object 的时候,会在 singletonObject 的存储器中加入此 object,而在其他的两个存储器中移除。当然,这样的行为是可以在子类中去复写的。
在 getSingleton的时候,spring的默认实现是,先从 singleton object 的存储器中去寻找,如果找不到,再从 early singleton object 存储器中寻找,再找不到,那就在寻找对应的 singleton factory,造出所需的 singleton object,然后返回。
而 contains singleton 就是直接检查 singleton object 存储器了,其他的存储器不做检查。
而 get singleton counts 也是统计 singleton object 的数量。
看完了代码,再仔细想想,为什么这个类要使用三个存储器呢?
我想, singletonObjects 就是直观的存储着 singleton 的,而 singletonFactories 是存储的制造 singleton 的工厂,还有一个 earlySingletonObject, 在看了代码之后,我更觉得这是一个 singletonFactory 制造出来的 singleton 的缓存。
转载:
相关推荐
NULL 博文链接:https://lgd-java2eye.iteye.com/blog/756599
Spring的BeanFactory的接口的中文解释
Spring中ApplicationContext和beanfactory区别.rar
主要介绍了简单了解Spring中BeanFactory与FactoryBean的区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
spring之beanfactory 的一些基本知识与其关系使用
Spring教程 1 Spring框架概述 3 Spring是什么? 3 Spring的历史 4 Spring的使命(Mission Statement) 4 Spring受到的批判 4 Spring包含的模块 5 总结 6 Spring的IoC容器 6 用户注册的例子 7 面向接口编程 8 (用户...
对BeanFactory的相关所有接口的功能的关键点进行了总结描述,中文版本
主要介绍了简单了解Spring beanfactory循环依赖命名重复2大属性,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
NULL 博文链接:https://ylxy3058.iteye.com/blog/2223489
主要介绍了Spring BeanFactory和FactoryBean区别解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
主要给大家介绍了关于Spring中BeanFactory与FactoryBean接口的区别的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者使用Spring具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
本篇文章主要介绍了Spring中BeanFactory解析bean详解 ,详细的介绍了使用BeanFactory对bean进行解析的实例,有兴趣的可以了解一下。
NULL 博文链接:https://364232252.iteye.com/blog/2369489
Spring BeanFactory Spring IOC(控制翻转)/DI(依赖注入) Spring Proxy Spring AOP 面向切面编程 Spring与JDBC整合 Spring声明式事务 Spring与Hibernate整合 Spring与Struts整合
spring3中实例化BeanFactory的3中方法
Spring注解驱动开发第41讲——Spring IOC容器创建源码解析(一)之BeanFactory的创建以及预准备工作(合起来整个过程)
NULL 博文链接:https://bjameng.iteye.com/blog/1468057
Spring的IoC容器之BeanFactory[定义].pdf
BeanFactory是用于访问Spring Bean容器的根接口,是一个单纯的Bean工厂,也就是常说的IOC容器的顶层定义,各种IOC容器是在其基础上为了满
Spring的IoC容器之BeanFactory 4.1 拥有BeanFactory之后的生活 4.2 BeanFactory的对象注册与依赖绑定方式 4.3 BeanFactory的XML之旅 4.4 容器背后的秘密 4.5 小结 Spring IoC容器ApplicationContext 5.1 统一资源...