上文对Spring IOC容器的核心BeanFactory接口分析发现:在默认Bean工厂DefaultListableBeanFactory中对象不是以Object形成存储,而是以BeanDefinition类封装后存放在并发容器ConcurrentHashMap中的,如下所示:

/** Map of bean definition objects, keyed by bean name */
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>(256);

下面来对BeanDefinition接口进行分析。

BeanDefinition

首先来看一幅图,BeanDefinition接口的UML类图关系:

可以看到BeanDefinition接口继承了两个接口,这两个接口均为祖宗级接口。AtributeAccessor位于spring-core包下,定义了属性的操作方式;BeanMetadataElement位于spring-beans包下,定义了获取元数据元素的配置源。其源码如下:

package org.springframework.beans.factory.config;

import org.springframework.beans.BeanMetadataElement;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.core.AttributeAccessor; public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement { String SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON; String SCOPE_PROTOTYPE = ConfigurableBeanFactory.SCOPE_PROTOTYPE; int ROLE_APPLICATION = 0; int ROLE_SUPPORT = 1; int ROLE_INFRASTRUCTURE = 2; void setParentName(String parentName); String getParentName(); void setBeanClassName(String beanClassName); String getBeanClassName(); void setScope(String scope); String getScope(); void setLazyInit(boolean lazyInit); boolean isLazyInit(); void setDependsOn(String... dependsOn); String[] getDependsOn(); void setAutowireCandidate(boolean autowireCandidate); boolean isAutowireCandidate(); void setPrimary(boolean primary); boolean isPrimary(); void setFactoryBeanName(String factoryBeanName); String getFactoryBeanName(); void setFactoryMethodName(String factoryMethodName); String getFactoryMethodName(); ConstructorArgumentValues getConstructorArgumentValues(); MutablePropertyValues getPropertyValues(); boolean isSingleton(); boolean isPrototype(); boolean isAbstract(); int getRole(); String getDescription(); String getResourceDescription(); BeanDefinition getOriginatingBeanDefinition();
}

考虑到篇幅限制,将源码中注释部分去掉。从接口名字即可大致知道该接口实现了哪些功能。

  • setParentName(String parentName)getParentName()可以设置获取该bean的父类bean
  • setBeanClassName(String beanClassName)getBeanClassName()可以设置获取该bean的别名
  • setLazyInit(boolean lazyInit)读取配置文件,设置该bean是否延迟加载;isLazyInit()判断该bean是否延迟加载
  • setDependsOn(String... dependsOn)设置bean的依赖项,String[] getDependsOn()获取依赖项
  • setFactoryBeanName(String factoryBeanName)设置该bean的加载工厂,String getFactoryBeanName()获取bean的加载工厂

通过对接口方法分析,可以发现BeanDefinition定义了bean实例的基础方法,基本上通过BeanDefinition接口就可以描述一个bean对象。也即表面在beanDefinitionMap中BeanDefinition接口可以替代Object对象存储bean实例。

既然两者都可以存储bean对象,为啥是用BeanDefinition而不是Object呢?其实细究可以发现:在Spring中,我们可以自定义是否延迟加载bean对象,合适初始化对象,要想实现加载、初始化时机控制,简单的通过Object对象是无法实现的,必须在此基础上有一个封装,这样才可以实现更多的自定义性质。所以在beanDefinitionMap中bean对象是以BeanDefinition形式存储。

本文介绍了Spring IOC容器中一个非常重要的接口BeanDefinition,以及解释了为啥beanDefinitionMap中存储的是BeanDefinition。下文将进入Spring IOC类加载的具体过程,重点看看默认的bean工厂DefaultListableBeanFactory

Spring IOC容器分析(2) -- BeanDefinition的更多相关文章

  1. Spring IOC容器分析(4) -- bean创建获取完整流程

    上节探讨了Spring IOC容器中getBean方法,下面我们将自行编写测试用例,深入跟踪分析bean对象创建过程. 测试环境创建 测试示例代码如下: package org.springframe ...

  2. Spring IOC容器分析(3) -- DefaultListableBeanFactory

    上一节介绍了封装bean对象的BeanDefinition接口.从前面小结对BeanFactory的介绍中,我们知道bean对象是存储在map中,通过调用getBean方法可以得到bean对象.在接口 ...

  3. Spring IOC容器分析(1) -- BeanFactory

    搭建好源码阅读环境后,就可以慢慢走进Spring殿堂了.IOC是Inversion of Control的缩写,控制反转的意思.很多人可能都知道IOC是spring的核心,将对象的创建初始化等权限交由 ...

  4. Spring Ioc 容器初始化过程

    IOC 是如何工作的? 通过 ApplicationContext 创建 Spring 容器,容器读取配置文件 "/beans.xml" 并管理定义的 Bean 实例对象.   通 ...

  5. Spring源码分析-从@ComponentScan注解配置包扫描路径到IoC容器中的BeanDefinition,经历了什么(一)?

    阅前提醒 全文较长,建议沉下心来慢慢阅读,最好是打开Idea,点开Spring源码,跟着下文一步一步阅读,更加便于理解.由于笔者水平优先,编写时间仓促,文中难免会出现一些错误或者不准确的地方,恳请各位 ...

  6. Spring源码分析:Spring IOC容器初始化

    概述: Spring 对于Java 开发来说,以及算得上非常基础并且核心的框架了,在有一定开发经验后,阅读源码能更好的提高我们的编码能力并且让我们对其更加理解.俗话说知己知彼,百战不殆.当你对Spri ...

  7. 【spring源码分析】spring ioc容器之前生今世--DefaultListableBeanFactory源码解读

    spring Ioc容器的实现,从根源上是beanfactory,但真正可以作为一个可以独立使用的ioc容器还是DefaultListableBeanFactory,因此可以这么说, DefaultL ...

  8. Spring IOC 容器源码分析 - 填充属性到 bean 原始对象

    1. 简介 本篇文章,我们来一起了解一下 Spring 是如何将配置文件中的属性值填充到 bean 对象中的.我在前面几篇文章中介绍过 Spring 创建 bean 的流程,即 Spring 先通过反 ...

  9. Spring IOC 容器源码分析 - 创建单例 bean 的过程

    1. 简介 在上一篇文章中,我比较详细的分析了获取 bean 的方法,也就是getBean(String)的实现逻辑.对于已实例化好的单例 bean,getBean(String) 方法并不会再一次去 ...

随机推荐

  1. hdu 5937 -- Equation(搜索)

    题目链接 problem description Little Ruins is a studious boy, recently he learned addition operation! He ...

  2. 【BZOJ】1015 [JSOI2008]星球大战starwar(并查集+离线处理)

    Description 很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统治者整个星系.某一天,凭着一个偶然的机遇,一支反抗军摧毁了帝国的超级武器,并攻下了星系中几乎所有的星球.这些星球通过 ...

  3. Theano学习-scan循环

    \(1.Scan\) 通用的一般形式,可用于循环 减少和映射(对维数循环)是特殊的 \(scan\) 对输入序列进行 \(scan\) 操作,每一步都能得到一个输出 \(scan\) 能看到定义函数的 ...

  4. PHP字符串函数-trim()实例用法

    string trim ( string $str [, string $charlist = " \t\n\r\0\x0B" ] )此函数返回字符串 str 去除首尾空白字符后的 ...

  5. C#中回车出发事件(+收藏)

    本文给大家介绍如何在c# winform中实现回车事件和回车键触发按钮的完美写法 我们常常要在c# winform中实现回车(enter)提交功能,这样比手动按按钮触发更快. 要完成回车按按钮功能,只 ...

  6. php用PHPExcel库生成Excel文档的例子

    <?php require_once '../libs/PHPWord/PHPWord.php'; require_once '../libs/PHPWord/PHPWord/IOFactory ...

  7. Python 中的装饰器

    说到装饰器是我们每个学Python人中的心痛. 装饰器作用:是用来装饰其他函数的,为其他函数添加新功能. 原则:1.不能改变被修饰函数的源代码. 2.不能修改被修饰函数的调用方式. 学装饰器前还需要了 ...

  8. linux 守护进程编程

    概述: Daemon运行在后台也称作"后台服务进程". 它是没有控制终端与之相连的进程.它独立于控制终端.通常周期的执行某种任务. 守护进程脱离终端是为了避免进程在执行过程中的信息 ...

  9. Babel运行原理

    前言     之前翻博客园的时候,看到有人朋友分享阿里巴巴的面试题,其中有一道题就是关于ES6转ES5 原理的,当时我看到感觉到自己离去阿里巴巴的路还很远啊,像我们大部分做开发的时候,都只知其然不知 ...

  10. 见到过的MOS管的一些参数

    选择MOS管的时候需要注意的几个参数1,VDSS(击穿电压):此电压要选择合适,一般是加入的电压值的峰值的两倍.2,VGS(th)(开启电压):3,RDS(on)(漏源电阻):这个值要尽可能的小,因为 ...