@

在讲容器之前,再明确一下知识点。

  • BeanDefinition是Bean在容器的描述。BeanDefinition与Bean不是一个东西。
  • Bean是根据BeanDefinition创建出来的。也即是我们所说的对象。

BeanDefinition物料需要有地方存储,Bean成品需要有地方存。今天我们讲讲仓库。

BeanFactory家族



此图是默认容器DefaultListableBeanFactory的继承,实现关系图.我们从右向左来分析下.

  1. BeanFactory接口:

    容器顶级接口,提供了容器最基本的能力,包括获取bean,是否包含bean,是否单例,获取bean类型,Bean的别名等方法。

  2. ListableBeanFactory接口:

    BeanFactory的子接口;具有批量获取Bean的能力

  3. HierarchicalBeanFactory接口:具有访问父容器的能力。有层次的BeanFactory。

  4. AutowireCapableBeanFactory接口:继承BeanFactory,扩展了自动装配能力。这个接口更多的作用是用于于与其他框架集成,把不在spring容器中的Bean加入到Spring容器生命周期管理中来。此接口很少用

  5. ConfigurableBeanFactory:定义了BeanFactory的配置。继承HierarchicalBeanFactory和SingletonBeanRegistry接口。实现了此接口的容器,具有层次,单例BeanDefinition注册功能。

  6. ConfigurableListableBeanFactory:

    大融合接口,除了具有上述接口的能外,还具有:类加载器,类型转化,属性编辑器,BeanPostProcessor,作用域,bean定义,处理bean依赖关系, bean销毁等功能。

  7. SingletonBeanRegistry接口: 具有Bean的操作能力.注册,查询,获取Bean数量等能力. 注意此处的Bean是实例.区别于BeanDefinition.

  8. SimpleAliasRegistry:Bean的别名操作类,实现了AliasRegistry.具有存储Bean别名,注册Bean别名,获取Bean别名的功能.aliasMap属性存储Bean别名

  9. DefaultSingletonBeanRegistry:除了继承了SimpleAliasRegistry的功能外. 最重要的是实现了SingletonBeanRegistry接口.具有存储Bean实例,注册Bean,获取Bean的能力.我们定义的被Spring管理的Class类的实例对象,以及实例的之间的相互依赖关系都是存储在此类中.默认常用的容器DefaultListableBeanFactory的Bean的相关能力.就是通过间接继承此类来实现的.

	/** Disposable bean instances: bean name --> disposable instance */
private final Map<String, Object> disposableBeans = new LinkedHashMap<String, Object>(); /** Map between containing bean names: bean name --> Set of bean names that the bean contains */
private final Map<String, Set<String>> containedBeanMap = new ConcurrentHashMap<String, Set<String>>(16); /** Map between dependent bean names: bean name --> Set of dependent bean names */
private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<String, Set<String>>(64); /** Map between depending bean names: bean name --> Set of bean names for the bean's dependencies */
private final Map<String, Set<String>> dependenciesForBeanMap = new ConcurrentHashMap<String, Set<String>>(64)
  1. FactoryBeanRegistrySupport: 提供多工厂Bean的支持.FactoryBean通过其名字我也可以看出是生产Bean的Bean.
  2. AbstractBeanFactory抽象类: 承上启下.从图中我们看出. AbstractBeanFactory.通过继承关系,继承FactoryBeanRegistrySupport各种能力.而且实现了右边部分接口.已然是比较完备的Bean容器了.AbstractBeanFactory还通过模板模式定义了获取Bean的算法骨架,
  3. AbstractAutowireCapableBeanFactory: .具有大部分的能力. 实现了AbstractBeanFactory定义的模板方法.其中doCreateBean方法逻辑是把一个BeanDefinition变成Bean的过程.这个方法非常重要.通常我们使用类创建对象.直接new出来. spring把BeanDefinition到Bean的过程模板化,留下了很多扩展点. 留给使用者可以在不同的时刻自定义BeanDefition创建Bean的过程.
  4. DefaultListableBeanFactory常用的默认容器实现,也是spring最常使用的容器类.看左边DefaultListableBeanFactory实现了BeanDefinitionRegistry接口. 这说明什么?说明DefaultListableBeanFactory具有存储BeanDefinition,操作BeanDefinition的能力.DefaultListableBeanFactory通过继承关系也具有了Bean的存储操作功能.

小结:

  1. BeanFactory体系,接口分明,完美的体现了接口分离原则。
  2. BeanFactory体系中有两种存储,一种是BeanDefinition的存储,另一个是Bean的存储.
  3. DefaultListableBeanFactory作为最常用的容器类.不但具有BeanDefinition的存储操作功能,而且通过继承具有Bean的存储操作功能.DefaultListableBeanFactory把存储的BeanDefinition通过一定算法创建Bean并存储起来.

BeanDefinition,BeanFactory,Bean三者关系

通过上面的对各个接口,类的认识.我们再来看看三者的关系.

我们向BeanFactory容器中注入一个BeanDefinition。BeanFactory帮我们存储起来.当我们想要得到一个Bean时.BeanFactory 帮我们把BeanDefinition创建Bean.并缓存起来.这个创建过程是可参与的.

  • BeanFactory保存了BeanDefiniton与Bean.
  • BeanFactory具有使用BeanDefinition创建Bean的功能
  • BeanFactory允许使用者可以干预BeanDefinition生成Bean的功能.

BeanFactory中的扩展点

设计原则之开闭原则说的特别好:说一个软件实体应该通过扩展来实现变化.

很多优秀的框架都有类似的扩展点设计,列如:

  • Tomcat中的Filter
  • Tomcat中的pipline-valve
  • springmvc中的Interceptor

BeanFactory中从BeanDefinition到Bean并不是一下子就完成的.这有一个过程.spring正是在这个过程中留下扩展点.来实现BeanDefinition到Bean的过程中的各种自定义变化.

从上面我们得知:AbstractAutowireCapableBeanFactory中有个doCreateBean()正是BeanDefinition到Bean的创建方法.接下来我们看看这个方法.有哪些扩展点:

  1. xxxAware接口:使Bean可以获得xxx. 列如实现了BeanFactoryAware接口的类,可以在该Bean被加载的过程中获取加载该Bean的BeanFactory
  2. BeanPostProcessor:BeanPostProcessor接口定义的两个方法,分别在bean的初始化方法(InitializingBean接口,或者init-method定义)执行的前后执行
  3. InitializingBean接口: 实现了InitializingBean接口的类,执行afterPropertiesSet
  4. 自定义的init-method方法:

总结:

BeanFactory是物料与成品仓库,并配生产线,把BeanDefinition生产成Bean 。BeanFactory留下很多扩展点, 方便开发人员可以参与BeanDefinition到Bean的创建过程.

欢迎大家关注我的公众号【源码行动】,最新个人理解及时奉送。

spring源码分析系列3:BeanFactory核心容器的研究的更多相关文章

  1. 【Spring源码分析系列】结构组成和容器的基本实现

    beans包的层级结构 src/main/java:用于展现Spring的主要逻辑 src/main/resources:用于存放系统的配置文件 src/test/java:用于对主要逻辑单元进行测试 ...

  2. spring源码分析系列 (8) FactoryBean工厂类机制

    更多文章点击--spring源码分析系列 1.FactoryBean设计目的以及使用 2.FactoryBean工厂类机制运行机制分析 1.FactoryBean设计目的以及使用 FactoryBea ...

  3. spring源码分析系列

    spring源码分析系列 (1) spring拓展接口BeanFactoryPostProcessor.BeanDefinitionRegistryPostProcessor spring源码分析系列 ...

  4. spring源码分析系列 (5) spring BeanFactoryPostProcessor拓展类PropertyPlaceholderConfigurer、PropertySourcesPlaceholderConfigurer解析

    更多文章点击--spring源码分析系列 主要分析内容: 1.拓展类简述: 拓展类使用demo和自定义替换符号 2.继承图UML解析和源码分析 (源码基于spring 5.1.3.RELEASE分析) ...

  5. spring源码分析系列 (1) spring拓展接口BeanFactoryPostProcessor、BeanDefinitionRegistryPostProcessor

    更多文章点击--spring源码分析系列 主要分析内容: 一.BeanFactoryPostProcessor.BeanDefinitionRegistryPostProcessor简述与demo示例 ...

  6. spring源码分析系列 (2) spring拓展接口BeanPostProcessor

    Spring更多分析--spring源码分析系列 主要分析内容: 一.BeanPostProcessor简述与demo示例 二.BeanPostProcessor源码分析:注册时机和触发点 (源码基于 ...

  7. spring源码分析系列 (3) spring拓展接口InstantiationAwareBeanPostProcessor

    更多文章点击--spring源码分析系列 主要分析内容: 一.InstantiationAwareBeanPostProcessor简述与demo示例 二.InstantiationAwareBean ...

  8. spring源码分析系列 (15) 设计模式解析

    spring是目前使用最为广泛的Java框架之一.虽然spring最为核心是IOC和AOP,其中代码实现中很多设计模式得以应用,代码看起来简洁流畅,在日常的软件设计中很值得借鉴.以下是对一些设计模式的 ...

  9. Spring源码分析(十九)容器的功能扩展概览

    摘要: 本文结合<Spring源码深度解析>来分析Spring 5.0.6版本的源代码.若有描述错误之处,欢迎指正. 经过前面几章的分析,相信大家已经对 Spring 中的容器功能有了简单 ...

随机推荐

  1. codeforces 828 D. High Load(思维,水题)

    题目链接:http://codeforces.com/contest/828/problem/D 题解:任意去一个点为根然后有几个k就是几个子叶也就是根结点有几个分支然后最好的解法就是贪心,将剩下的点 ...

  2. dp递推 数字三角形,dp初学者概念总结

    数字三角形(POJ1163)          在上面的数字三角形中寻找一条从顶部到底边的路径,使得路径上所经过的数字之和最大.路径上的每一步都只能往左下或 右下走.只需要求出这个最大和即可,不必给出 ...

  3. PAT 天梯杯 L2-014 列车调度

    火车站的列车调度铁轨的结构如下图所示. Figure 两端分别是一条入口(Entrance)轨道和一条出口(Exit)轨道,它们之间有N条平行的轨道.每趟列车从入口可以选择任意一条轨道进入,最后从出口 ...

  4. 爬虫基本知识之C/S交互

    概念 爬虫就是对网页的获取. 一般获取的网页中又有通向其他网页的通路,我们叫做超链接,那么就可以通过这样的通路获取更多其他的网页,就像一只在网路上爬行的蜘蛛,所以俗称爬虫. 爬虫的工作原理和浏览器浏览 ...

  5. springmvc——@InitBinder注解

    转自http://www.cnblogs.com/douJiangYouTiao888/p/6765220.html 有些类型的数据是无法自动转换的,比如请求参数中包含时间类型的数据,无法自动映射到C ...

  6. python自学Day02(自学书籍python编程从入门到实践)

    第三章 列表简介 3.1 列表是什么 按特定顺序排列的元素组成. 元素类型可以是任意数据类型. 元素之间没有任何的关系. 在python中用中括号 [] 括起来并用 ,号隔开 3.1.1 访问列表元素 ...

  7. MATLAB之图像与音频信号处理

    原理简介 离散傅立叶.离散余弦和离散小波变换是图像.音频信号常用基础操作,时域信号转换到不同变换域以后,会导致不同程度的能量集中,信息隐藏利用这个原理在变换域选择适当位置系数进行修改,嵌入信息,并确保 ...

  8. KafkaProducer源码分析

    Kafka常用术语 Broker:Kafka的服务端即Kafka实例,Kafka集群由一个或多个Broker组成,主要负责接收和处理客户端的请求 Topic:主题,Kafka承载消息的逻辑容器,每条发 ...

  9. 6 个 K8s 日志系统建设中的典型问题,你遇到过几个?

    作者 |  元乙  阿里云日志服务数据采集客户端负责人,目前采集客户端 logtail 在集团百万规模部署,每天采集上万应用数 PB 数据,经历多次双 11.双 12 考验. 导读:随着 K8s 不断 ...

  10. rpm简单使用

    rpm描述:利用源码包编译成rpm时,会去指定安装好这个包的位置本质:解压,然后拷贝到相关的目录,然后执行脚本 vstpd-3.0.2-9.el7.x86_64.rpm 包名 版本 release 架 ...