Bean的定义主要由BeanDefinition来描述的。作为Spring中用于包装Bean的数据结构,今天就来看看它的面纱下的真容吧。

首先就是BeanDefinition的类定义:

public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement
复制代码

对,没错,这货是个接口,而不是类,是不是有点莫名奇妙呢?我们都知道在JAVA中,接口是不能用来new出新的对象的,那么在Spring中,到底将XML解析出来的Bean包装成了什么呢?(这个密等下揭开)

先来看看BeanDefinition一个继承结构吧(均是与BeanDefinition有直接关联的类或者接口)!

从类图中可以看出,BeanDefinition继承了AttributeAccessor和BeanMetadataElement两个接口;一个一个看。

AttributeAccessor

AttributeAccessor接口定义了最基本的对任意对象的元数据的修改或者获取,主要方法有:

//将name定义的属性设置为提供的value值。如果value的值为null,则该属性为{@link #removeAttribute removed}。
//通常,用户应该注意通过使用完全限定的名称(可能使用类或包名称作为前缀)来防止与其他元数据属性重叠。
void setAttribute(String name, Object value);
//获取标识为name的属性的值。
Object getAttribute(String name);
//删除标识为name的属性,并返回属性值
Object removeAttribute(String name);
//如果名为name的属性是否存在,存在返回true,否则返回false。
boolean hasAttribute(String name);
//返回所有属性的名称。
String[] attributeNames();
复制代码

BeanMetadataElement

BeanMetadataElement接口提供了一个getResource()方法,用来传输一个可配置的源对象。

//返回此元数据元素的配置源对象(可能为null)。
Object getSource();
复制代码

BeanDifinition源码分析

一个BeanDefinition描述了一个bean的实例,包括属性值,构造方法参数值和继承自它的类的更多信息。BeanDefinition仅仅是一个最简单的接口,主要功能是允许BeanFactoryPostProcessor 例如PropertyPlaceHolderConfigure 能够检索并修改属性值和别的bean的元数据(译注)。

//标准单例作用域的作用域标识符:“singleton”。
//对于扩展的bean工厂可能支持更多的作用域。
String SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON;
复制代码
//标准原型作用域的范围标识符:“prototype”。
//对于扩展的bean工厂可能支持更多的作用域。
String SCOPE_PROTOTYPE = ConfigurableBeanFactory.SCOPE_PROTOTYPE;
复制代码
//表示BeanDefinition是应用程序主要部分的角色提示。 通常对应于用户定义的bean。
int ROLE_APPLICATION = 0;
复制代码

ROLE_SUPPORT =1实际上就是说,我这个Bean是用户的,是从配置文件中过来的。

//表示BeanDefinition是某些大型配置的支持部分的角色提示,通常是一个外部ComponentDefinition。
//当查看某个特定的ComponentDefinition时,认为bean非常重要,
//以便在查看应用程序的整体配置时能够意识到这一点。
int ROLE_SUPPORT = 1;
复制代码

ROLE_INFRASTRUCTURE = 2就是我这Bean是Spring自己的,和你用户没有一毛钱关系。

//角色提示表明一个BeanDefinition是提供一个完全背景的角色,并且与最终用户没有关系。
//这个提示用于注册完全是ComponentDefinition内部工作的一部分的bean
int ROLE_INFRASTRUCTURE = 2;
复制代码

上面是BeanDifinition的一些基本属性信息,一个就是标识下当前Bean的作用域,另外就是标识一下这个Bean是内部的还是外部的。下面来看这个接口为其子类都提供了哪些具体的行为方法:

1.当前Bean父类名称get&set方法

//如果父类存在,设置这个bean定义的父定义的名称。
void setParentName(String parentName);
//如果父类存在,则返回当前Bean的父类的名称
String getParentName();
复制代码

2.当前Bean的className get&set方法

//指定此bean定义的bean类名称。
//类名称可以在bean factory后期处理中修改,通常用它的解析变体替换原来的类名称。
void setBeanClassName(String beanClassName);//返回此bean定义的当前bean类名称。
//需要注意的是,这不一定是在运行时使用的实际类名,以防子类定义覆盖/继承其父类的类名。
//此外,这可能只是调用工厂方法的类,或者它 在调用方法的工厂bean引用的情况下甚至可能是空的。
//因此,不要认为这是在运行时定义的bean类型,而只是将其用于在单独的bean定义级别进行解析。
String getBeanClassName();
复制代码

3.Bean的作用域get&set方法

//覆盖此bean的目标范围,指定一个新的范围名称。
void setScope(String scope);
//返回此bean的当前目标作用域的名称,如果没有确定,返回null
String getScope();
复制代码

4.懒加载的get&set方法

//设置这个bean是否应该被延迟初始化。如果{false},那么这个bean将在启动时由bean工厂实例化,
//这些工厂执行单例的立即初始化。
//懒加载 <bean lazy-init="true/false">
void setLazyInit(boolean lazyInit);
//返回这个bean是否应该被延迟初始化,即不是在启动时立即实例化。只适用于单例bean。
boolean isLazyInit();
复制代码

5.依赖关系设置

//设置这个bean依赖被初始化的bean的名字。 bean工厂将保证这些bean首先被初始化。
//<bean depends-on="">
void setDependsOn(String... dependsOn);
//返回这个bean依赖的bean名称。
String[] getDependsOn();
复制代码

6.是否是自动转配设置

//设置这个bean是否是获得自动装配到其他bean的候选人。
//需要注意是,此标志旨在仅影响基于类型的自动装配。
//它不会影响按名称的显式引用,即使指定的bean没有标记为autowire候选,也可以解决这个问题。
//因此,如果名称匹配,通过名称的自动装配将注入一个bean。
void setAutowireCandidate(boolean autowireCandidate);//返回这个bean是否是自动装配到其他bean的候选者。就是是否在其他类中使用autowired来注入当前Bean的
//是否为被自动装配 <bean autowire-candidate="true/false">
boolean isAutowireCandidate();
复制代码

7.主候选Bean

//是否为主候选bean    使用注解:@Primary
void setPrimary(boolean primary);
//返回这个bean是否是主要的autowire候选者。
boolean isPrimary();
复制代码

8.定义创建该Bean对象的工厂类

//指定要使用的工厂bean(如果有的话)。 这是调用指定的工厂方法的bean的名称。
void setFactoryBeanName(String factoryBeanName);
//返回工厂bean的名字,如果有的话。
String getFactoryBeanName();
复制代码

9.创建该Bean对象的工厂方法

//如果有的话,指定工厂方法。
//这个方法先将通过构造函数参数被调用,或者如果参数,将调用该方法的无参数构造。
//方法将在指定的工厂bean(如果有的话)上被调用,或者作为本地bean类的静态方法被调用。
void setFactoryMethodName(String factoryMethodName);
//如果存在,返回工厂方法名
String getFactoryMethodName();
复制代码

10.返回此bean的构造函数参数值。

//返回此bean的构造函数参数值。
ConstructorArgumentValues getConstructorArgumentValues();
复制代码

11.获取普通属性集合

//获取普通属性集合
MutablePropertyValues getPropertyValues();
复制代码

12.当前Bean的基本特性

//是否是单例的
boolean isSingleton();
//是否是多例的
boolean isPrototype();
//是否是抽象类
boolean isAbstract();
复制代码

13.当前Bean的应用

//获取这个bean的应用
int getRole();
复制代码

13.可读描述

//返回对bean定义的可读描述。
String getDescription();
复制代码
//返回该bean定义来自的资源的描述
String getResourceDescription();
复制代码
//返回原始的BeanDefinition;如果没有,则返回null。允许检索装饰的bean定义(如果有的话)。
//注意,这个方法返回直接的发起者。 迭代原始链,找到用户定义的原始BeanDefinition。
BeanDefinition getOriginatingBeanDefinition();
复制代码

从上面的属性和方法分析可以看出,BeanDefinition对于一个Bean的描述做了较为完整的一套约束。这为后续的子类提供的最基本的职责和属性。

欢迎关注glmapper工作室公众号

Spring源码系列:BeanDefinition源码解析相关推荐

  1. Java集合Collection源码系列-ArrayList源码分析

    Java集合系列-ArrayList源码分析 文章目录 Java集合系列-ArrayList源码分析 前言 一.为什么想去分析ArrayList源码? 二.源码分析 1.宏观上分析List 2.方法汇 ...

  2. Spring AOP 源码系列(一)解析 AOP 配置信息

    在进行源码阅读之前建议先看一下这篇文章:Spring AOP 源码分析系列文章导读 by 田小波,写的非常好,推荐阅读. 关于 AOP 中常用的一些术语这里就不解释了,如果不清楚的建议先看一遍上面推荐 ...

  3. JUC源码系列-CountDownLatch源码研读

    前言 CountDownLatch是一个很有用的工具,latch是门闩的意思,该工具是为了解决某些操作只能在一组操作全部执行完成后才能执行的情景.例如,小组早上开会,只有等所有人到齐了才能开:再如,游 ...

  4. Spring源码系列:BeanDefinition载入(下)

    在Spring源码系列:BeanDefinition载入(上)中已经大概捋了一下解析过程,本篇将记录一下bean的注册过程. bean的注册就是DefaultListableBeanFactory中r ...

  5. Ioc容器beanDefinition-Spring 源码系列(1)

    Ioc容器beanDefinition-Spring 源码系列(1) 目录: Ioc容器beanDefinition-Spring 源码(1) Ioc容器依赖注入-Spring 源码(2) Ioc容器 ...

  6. Spring源码系列:依赖注入(二)createBean

    在Spring源码系列:依赖注入(一)(AbstractBeanFactory-getBean)最后说道getBean是依赖注入的起点,bean的创建都是通过createBean来完成具体的创建的.c ...

  7. Spring源码系列(十二)Spring创建Bean的过程(二)

    1.写在前面 上篇博客主要Spring在创建Bean的时候,第一次调用的Bean的后置处理器的过程,同时笔者也打算将整个Spring创建的Bean的过程,通过这个系列,将Bean的创建过程给讲清楚,废 ...

  8. Spring源码系列- Spring Beans - 核心类的基本介绍

    Spring源码系列- Spring Beans - 核心类的基本介绍 读过上一篇文章的读者应该都能对Spring的体系结构有一个大致的了解,在结尾处,我也说过会从spring-beans包开始分析, ...

  9. spring 源码分析(1)-xml文件解析

    我们在最开始接触spring的时候,看到不少书spring入门的例子如下 ApplicationContext atx = new ClassPathXmlApplicationContext(&qu ...

  10. Spring 4.x 源码系列4-创建bean实例

    创建bean实例(createBeanInstance 方法) AbstractAutowireCapableBeanFactory 的 createBeanInstance 方法实现了创建 bean ...

最新文章

  1. jupyter notebook中%与!的区别
  2. jsp图片上传(commons-fileupload组件)
  3. php utf8 html字符,PHP:utf-8编码,htmlentities给出了奇怪的结果
  4. 03_dbcp数据源依赖jar包,DBCP中API介绍,不同过dbcp方式使用dbcp数据库连接池,通过配置文件使用dbcp数据库连接池
  5. HDU 1025 Constructing Roads In JGShining's Kingdom(DP+二分)
  6. Gini 系数与熵的关系
  7. 国密SM2算法的只求理解不求甚解 (5/5)SM2算法签名验签协议
  8. java万年历项目百度云_Java开发万年历
  9. 【vulhub】conference
  10. 华为 AR系列路由器密码重置
  11. 微商卖养生产品怎么吸粉?让客户慢慢进入你的营销场景
  12. c语言魂斗罗小游戏代码,(搬运)魂斗罗系列游戏秘籍(包含一些解锁要数)
  13. 省市县及对应编码-json格式
  14. 分布式事务方案Seata
  15. thinkpad笔记本电脑更换固态硬盘
  16. GDI+ 绘图闪烁解决方法
  17. 数据之美(五):美不胜收的数据图(上)
  18. js字符串日期直接比较大小
  19. Error querying database. Cause: java.lang.NullPointerException .The error occurred while handlin
  20. 推荐windows系统10款好用的软件,让你使用体验飞升

热门文章

  1. 【ZJOI 2008】树的统计 Count
  2. j2ee下的单元测试小工具
  3. 剑指offer4:重建二叉树
  4. 20145324 《信息安全系统设计基础》第十周学习总结
  5. mysql主从复制错误sql-running no
  6. 基础知识漫谈(3) 组合基础知识,设计游戏框架
  7. Android Fragment详解(二):Fragment创建及其生命周期
  8. 分支-03. 三天打鱼两天晒网(Switch…case)
  9. 2010年厦门商报报导《监控》小说
  10. matlab 比例谐振控制器,比例谐振控制的一种实现(含代码)