BeanDefinition

Spring容器启动的过程中,会将Bean解析成Spring内部的BeanDefinition结构。

不管是是通过xml配置文件的<Bean>标签,还是通过注解配置的@Bean,它最终都会被解析成一个Bean定义信息对象,最后我们的Bean工厂就会根据这份Bean的定义信息,对bean进行实例化、初始化等等操作。

从上可知BeanDefinition这个接口对Spring IoC容器的重要之处,所以了解好了它(以及子类),能让我们更大视野的来看Spring管理Bean的一个过程,也能透过现象看本质。

比喻

  1. Spring IoC容器好比一间餐馆
    当你来到餐馆,通常会直接招呼服务员:点菜!至于菜的原料是什么?如何用原料把菜做出来?可能你根本就不关心。IoC容器也是一样,你只需要告诉它需要某个bean,它就把对应的实例(instance)扔给你,至于这个bean是否依赖其他组件,怎样完成它的初始化,根本就不需要你关心。
  2. BeanDefinition就是做菜的原料
    容器中的每一个bean都会有一个对应的BeanDefinition实例,该实例负责保存bean对象的 所有 必要信息,包括bean对象的beanClass、scope、lazyInit类属性、是否是抽象类、构造方法和参数、其它属性等等(所以BeanDefinition就好比做菜的原料)
  3. BeanDefinitionRegistry和 BeanFactory就是菜谱
    BeanDefinitionRegistry抽象出bean的注册逻辑,而BeanFactory则抽象出了bean的管理逻辑。 各个BeanFactory的实现类就具体承担了bean的注册以及管理工作。

BeanDefinition源码

源码如下:

public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {// 单例Bean还是原型BeanString SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON;String SCOPE_PROTOTYPE = ConfigurableBeanFactory.SCOPE_PROTOTYPE;// Bean角色int ROLE_APPLICATION = 0; //应用程序重要组成部分int ROLE_SUPPORT = 1; //做为大量配置的一部分(支持、扩展类)  实际上就是说,我这个Bean是用户的,是从配置文件中过来的。int ROLE_INFRASTRUCTURE = 2; //指内部工作的基础构造  实际上是说我这Bean是Spring自己的,和你用户没有一毛钱关系// Modifiable attributes//parent definition(若存在父类的话,就设置进去)void setParentName(@Nullable String parentName);@NullableString getParentName();// 指定Class类型。需要注意的是该类型还有可能被改变在Bean post-processing阶段// 若是getFactoryBeanName  getFactoryMethodName这种情况下会改变void setBeanClassName(@Nullable String beanClassName);@NullableString getBeanClassName();//SCOPE_SINGLETON或者SCOPE_PROTOTYPE两种void setScope(@Nullable String scope);@NullableString getScope();// @Lazy 是否需要懒加载(默认都是立马加载的)void setLazyInit(boolean lazyInit);boolean isLazyInit();// 此Bean定义需要依赖的Bean(显然可以有多个)void setDependsOn(@Nullable String... dependsOn);@NullableString[] getDependsOn();// 这个Bean是否允许被自动注入到别的地方去(默认都是被允许的)// 注意:此标志只影响按类型装配,不影响byName的注入方式的~~~~void setAutowireCandidate(boolean autowireCandidate);boolean isAutowireCandidate();// 是否是首选的  @Primaryvoid setPrimary(boolean primary);boolean isPrimary();// 指定使用的工厂Bean(若存在)的名称~void setFactoryBeanName(@Nullable String factoryBeanName);@NullableString getFactoryBeanName();//指定工厂方法~void setFactoryMethodName(@Nullable String factoryMethodName);@NullableString getFactoryMethodName();// 获取此Bean的构造函数参数值们  ConstructorArgumentValues:持有构造函数们的 // 绝大多数情况下是空对象 new ConstructorArgumentValues出来的一个对象// 当我们Scan实例化Bean的时候,可能用到它的非空构造,这里就会有对应的值了,然后后面就会再依赖注入了ConstructorArgumentValues getConstructorArgumentValues();default boolean hasConstructorArgumentValues() {return !getConstructorArgumentValues().isEmpty();}// 获取普通属性集合~~~~MutablePropertyValues getPropertyValues();default boolean hasPropertyValues() {return !getPropertyValues().isEmpty();}// Read-only attributesboolean isSingleton();boolean isPrototype();boolean isAbstract();// 对应上面的role的值int getRole();//@Description@NullableString getDescription();// 返回该Bean定义来自于的资源的描述(用于在出现错误时显示上下文)@NullableString getResourceDescription();//返回原始BeanDefinition,如果没有则返回@null// 若这个Bean定义被代理、修饰过  这个方法可以返回原始的@NullableBeanDefinition getOriginatingBeanDefinition();
}

具体实现类

  1. AbstractBeanDefinition
    AbstractBeanDefinition实现了BeanDefinition定义的一系列操作,定义了描述Bean画像的一系列属性,在AbstractBeanDefinition的基础上,Spring衍生出了一系列具有特殊用途的BeanDefinition。

  2. GenericBeanDefinition
    标准通用的beanDefinition。除了具有指定类、可选的构造参数值和属性参数这些其它beanDefinition一样的特性外,它还具有通过parenetName属性来动态设置parent bean definition。

  3. ChildBeanDefinition
    子Bean定义信息,依赖于父类RootBeanDefinition
    ChildBeanDefinition是一种bean definition,它可以继承它父类的设置,即ChildBeanDefinition对RootBeanDefinition有一定的依赖关系。

  4. RootBeanDefinition
    一个RootBeanDefinition定义表明它是一个可合并的beanDefinition:即在spring beanFactory运行期间,可以返回一个特定的bean。但在Spring2.5以后,我们绝大多数情况还是可以使用GenericBeanDefinition来做。
    在 配置文件中可以定义父和子,父用RootBeanDefinition表示, 而子用ChildBeanDefiniton表示,而没有父的就使用 RootBeanDefinition表示。

  5. 子接口:AnnotatedBeanDefinition
    增加了一个注解元数据AnnotationMetadata取得方法。

AnnotatedBeanDefinition的三个子类:

1.ScannedGenericBeanDefinition

存储@Component、@Service、@Controller等注解注释的类
它的源码很简单,就是多了一个AnnotationMetadata 属性,用来存储一些注解信息。

2. AnnotatedGenericBeanDefinition

在基于注解驱动的Spring应用着,它使用得非常的多。因为获取注解信息非常的方便。
AnnotatedGenericBeanDefinition只能用于已经被注册或被扫描到的类。

3.ConfigurationClassBeanDefinition

首先需要注意的是,它是ConfigurationClassBeanDefinitionReader的一个私有的静态内部类:这个类负责将@Bean注解的方法转换为对应的ConfigurationClassBeanDefinition类。

ConfigurationClassBeanDefinition直接继承自RootBeanDefinition

它有一些默认的设置处理如下:
@Bean注解没有指定bean的名字,默认会用方法的名字命名bean
@Configuration注解的类会成为一个工厂类,而所有的@Bean注解的方法会成为工厂方法,通过工厂方法实例化Bean,而不是直接通过构造函数初始化(所以我们方法体里面可以很方便的书写逻辑。)

Spring - 理解BeanDefinition相关推荐

  1. Spring IOC BeanDefinition解析

    Spring IOC BeanDefinition解析 IOC(Inversion of Control)即控制反转,是说创建对象的控制权进行了转移,以前创建对象的主动权和创建时机是由自己把控的,而现 ...

  2. Spring中将BeanDefinition注册到IOC容器中

    Spring中将BeanDefinition注册到IOC容器中 XML配置元信息 <bean name="-" - /> 注解: @Bean,@Component,@I ...

  3. 第二篇 再读Spring 之 BeanDefinition解析

    第二篇 再读Spring 之 BeanDefinition解析 文章目录 第二篇 再读Spring 之 BeanDefinition解析 一.颗粒度问题 二.细说Spring中不同颗粒度对象在解析中的 ...

  4. 第四篇 再读Spring 之BeanDefinition注册

    文章目录 前言 一.管理的必要性 框架设计 工程实现 二.Spring的实现 1.抽象接口BeanDefinitionRegistry 2. 具体实现DefaultListableBeanFactor ...

  5. Spring之BeanDefinition详解

    前言 Spring在初始化过程中,将xml中定义的对象解析到了BeanDefinition对象中,我们有必要了解一下BeanDefinition的内部结构,有助于我们理解Spring的初始化流程. 一 ...

  6. 彻底理解Spring AOP

    目录 前言 1. AOP概念 2. AOP的实现 3. Spring的IoC理解: 4. Sping知识整理 前言 AOP英文名为Aspect Oriented Programming,意为面向切面编 ...

  7. 互相引用 spring_巧夺天工,这样理解Spring的IOC、DI下来,真的很清晰了

    前言 你可能会有如下问题: 想看Spring源码,但是不知道应当如何入手去看,对整个Bean的流程没有概念,碰到相关问题也没有头绪如何下手 看过几遍源码,没办法彻底理解,没什么感觉,没过一阵子又忘了本 ...

  8. spring源码系列一--BeanDefinition

    如果说java是由对象组成,那么spring-framework框架可以说是由BeanDefinition所构成.BeanDefinitiion其实是spring中的顶级接口,我们在阅读源码之前必须要 ...

  9. Spring官网阅读(四)BeanDefinition(上)

    前面几篇文章已经学习了官网中的1.2,1.3,1.4三小结,主要是容器,Bean的实例化及Bean之间的依赖关系等.这篇文章,我们继续官网的学习,主要是BeanDefinition的相关知识,这是Sp ...

  10. Spring : BeanDefinition

    1.美图 2.概述 在Java中,一切皆对象.在JDK中使用java.lang.Class来描述类这个对象. 在Spring中,存在bean这样一个概念,那Spring又是怎么抽象bean这个概念,用 ...

最新文章

  1. oracle 测试数据类型,oracle修改表字段的数据类型测试
  2. Struts2 (三)OGLN
  3. Celery中文翻译-Application
  4. 基因分子生物学(2)-DNA携带遗传特性
  5. Python3类方法和静态方法
  6. 【网络编程】之八、异步选择WSAAsyncSelect
  7. neo4j set 多个值_Neo4j:收集多个值
  8. python3中的zip_Python3实现将文件归档到zip文件及从zip文件中读取数据的方法
  9. 《JavaScript高级程序设计》笔记 - Map与Object的差异与选择
  10. SpringSecurity的认识和整合流程
  11. 再学 GDI+[63]: 路径画刷(3) - SetFocusScales、GetFocusScales
  12. HTML 5 新标签
  13. JSP技术-01-语法及运行原理
  14. idea好看字体设置
  15. 高德地图导航简单实例
  16. ui界面设计工具有哪些
  17. 爬虫爬取的网页源代码是\uxxxx格式的,如何进行解码?
  18. JAVA 清理垃圾文件简单实现
  19. 车辆调度管理系统,车辆调度管理系统的组成,车辆调度管理系统的作用
  20. dve 二维数组信号 显示波形_交互式仿真下dve和verdi中查看二维数组值

热门文章

  1. Widnows开启休眠
  2. Eclipse或者Myeclipse卡,慢的解决方法
  3. 第41课 WEB代理、Haproxy 配置详解及Haproxy ACL使用
  4. Atom 扩展离线安装
  5. Scrapy和MongoDB的应用---爬取
  6. 为什么每天扣我50无忧币?
  7. 10.Linux 高性能服务器编程 --- 信号
  8. 13.字符串,结构,联合
  9. 44. 将样式表放在顶部(5)
  10. 4. PSR-4 --- 自动加载