Spring组件BeanDefinition 源码解析
BeanDefinition
继承图

继承的接口
BeanMetadataElement接口
将由承载配置源对象的bean元数据元素的类实现。
包含一个getSource的方法,可以获取到MetaData对应的配置类的类对象(class对象)。
public interface BeanMetadataElement
/**
* 返回此元数据元素的配置源{@code Object}(可以为{@code null})。
* 如要配置的Bean类是A,那么getSource返回A.class
*/
@Nullable
default Object getSource() {
return null;
}
}
AttributeAccessor接口
定义用于 将metadata附加到任意对象 或 从任意对象访问metadata 的通用协定的接口。
包含设置属性、添加属性、获得属性等方法。
public interface AttributeAccessor {
/**
* 将{@code name}定义的属性设置为提供的{@code value}。
* 如果{@code value}为{@code null},则属性为{@link #removeAttribute remove}。
* <p>通常,用户应注意通过使用完全限定的名称(可能使用类或程序包名称作为前缀)来防止与其他元数据属性重叠。
* @param name 命名唯一属性键
* @param value 要附加的属性值
*/
void setAttribute(String name, @Nullable Object value);
/**
* 获取由{@code name}标识的属性的值。
* 如果属性不存在,则返回{@code null}。
* @param 命名唯一属性键
* @return 属性的当前值(如果有)
*/
@Nullable
Object getAttribute(String name);
/**
* 删除由{@code name}标识的属性,并返回其值。
* 如果未找到{@code name}下的属性,则返回{@code null}。
*
* @param name 命名唯一属性键
* @return 属性的最后一个值(如果有)
*/
@Nullable
Object removeAttribute(String name);
/**
* 如果由{@code name}标识的属性存在,则返回{@code true}。
* 否则,返回{@code false}。
*
* @param name 命名唯一属性键
*/
boolean hasAttribute(String name);
/**
* 返回所有属性的名称。
*/
String[] attributeNames();
}
新增属性和方法
BeanDefinition描述了一个bean实例,该实例具有属性值,构造函数参数值以及具体实现所提供的更多信息。 这只是一个最小的接口:主要目的是允许{@link BeanFactoryPostProcessor}自省和修改属性值和其他bean元数据。
主要定义了几种bean角色常量。包含对ParentName、BeanClassName、Scope、属性、构造函数参数列表、依赖的bean、是否是单例类、是否是LazyInit、工厂方法、init方法、destory方法等的存取,其实就是将Bean的定义信息存储到这个BeanDefinition相应的属性中,后面对Bean的操作就根据BeanDefinition进行,例如拿到这个BeanDefinition后,可以根据里面的类名、构造函数、构造函数参数,使用反射进行对象创建。
public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {
/**
* 标准单例作用域的作用域标识符:{@value}。
* <p>请注意,扩展的bean工厂可能支持更多范围。
*
* @see #setScope
* @see ConfigurableBeanFactory#SCOPE_SINGLETON
*/
String SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON;
/**
* 标准原型范围的范围标识符:{@value}。
* <p>请注意,扩展的bean工厂可能支持更多范围。
*
* @see #setScope
* @see ConfigurableBeanFactory#SCOPE_PROTOTYPE
*/
String SCOPE_PROTOTYPE = ConfigurableBeanFactory.SCOPE_PROTOTYPE;
/**
* 角色提示,指示{@code BeanDefinition}是应用程序的主要部分。
* 通常对应于用户定义的bean。
*/
int ROLE_APPLICATION = 0;
/**
* 角色提示,指示{@code BeanDefinition}是某些较大配置的支持部分,通常是外部{@link org.springframework.beans.factory.parsing.ComponentDefinition}。
* {@code SUPPORT} bean被认为很重要,足以在更仔细地查看特定的{@link org.springframework.beans.factory.parsing.ComponentDefinition}时要注意,但在查看Bean的整体配置时却不知道一个应用程序。
*
*/
int ROLE_SUPPORT = 1;
/**
* 角色提示,指示{@code BeanDefinition}正在提供完全后台的角色,与最终用户无关。
* 当注册完全属于{@link org.springframework.beans.factory.parsing.ComponentDefinition}内部工作的bean时,将使用此提示。
*
*/
int ROLE_INFRASTRUCTURE = 2;
// Modifiable attributes
/**
* 设置此bean定义的父定义的名称(如果有)。
*
*/
void setParentName(@Nullable String parentName);
/**
* 返回此bean定义的父定义的名称(如果有)。
*/
@Nullable
String getParentName();
/**
* 指定此Bean定义的Bean类名称。
* <p>可以在bean工厂后处理期间修改类名,通常用解析后的变体替换原始的类名。
*
* @see #setParentName
* @see #setFactoryBeanName
* @see #setFactoryMethodName
*/
void setBeanClassName(@Nullable String beanClassName);
/**
* 返回此Bean定义的当前Bean类名称。
* <p>请注意,在子定义从其父级继承/继承该子类名称的情况下,不必一定是在运行时使用的实际类名。
* 同样,这可能只是调用工厂方法的类,或者在调用工厂方法的工厂bean引用的情况下它甚至可能为空。
* 因此,<i>不要</ i>在运行时将其视为确定的bean类型,而仅将其用于单个bean定义级别的解析目的。
*
* @see #getParentName()
* @see #getFactoryBeanName()
* @see #getFactoryMethodName()
*/
@Nullable
String getBeanClassName();
/**
* 覆盖此bean的目标作用域,并指定一个新的作用域名称。
*
* @see #SCOPE_SINGLETON
* @see #SCOPE_PROTOTYPE
*/
void setScope(@Nullable String scope);
/**
* 返回此Bean的当前目标作用域的名称,如果未知,则返回{@code null}。
*
*/
@Nullable
String getScope();
/**
* 设置是否应延迟初始化此bean。
* <p>如果{@code false},则将在执行启动单例初始化的bean工厂启动时实例化bean。
*
*/
void setLazyInit(boolean lazyInit);
/**
* 返回此bean是否应延迟初始化,即不要在启动时急于实例化。
* 仅适用于单例bean。
*
*/
boolean isLazyInit();
/**
* 设置该bean依赖于初始化的bean的名称。
* Bean工厂将确保首先初始化这些Bean。
*/
void setDependsOn(@Nullable String... dependsOn);
/**
* 返回此bean依赖的bean名称。
*/
@Nullable
String[] getDependsOn();
/**
* 设置此bean是否适合自动连接到其他bean。
* <p>请注意,此标志旨在仅影响type-based(基于类型的)的自动装配(autowiring)。
* 它不会影响按name的显式引用,如果指定的bean未标记为autowire候选也可以被解析。
* 因此,如果名称匹配,按名称自动装配仍将注入Bean。
*/
void setAutowireCandidate(boolean autowireCandidate);
/**
* 返回此bean是否适合自动连接到其他bean。
*/
boolean isAutowireCandidate();
/**
* 设置此bean是否为自动装配的主要候选对象。
* <p>如果对于多个匹配候选对象中的一个bean,此值为{@code true},则它将作为平局。
*/
void setPrimary(boolean primary);
/**
* 返回此Bean是否为自动装配的主要候选对象。
*/
boolean isPrimary();
/**
* 指定要使用的 factory bean(如果有)。
* 这是用于调用指定工厂方法的bean的名称。
*
* @see #setFactoryMethodName
*/
void setFactoryBeanName(@Nullable String factoryBeanName);
/**
* 返回工厂bean名称(如果有)。
*/
@Nullable
String getFactoryBeanName();
/**
* 指定工厂方法(如果有)。
* 将使用构造函数参数调用此方法,如果未指定任何参数,则不使用任何参数。
* 该方法将在指定的factory bean(如果有)上被调用,否则将作为本地bean类上的静态方法被调用。
*
* @see #setFactoryBeanName
* @see #setBeanClassName
*/
void setFactoryMethodName(@Nullable String factoryMethodName);
/**
* 返回工厂方法名(如果有)。
*/
@Nullable
String getFactoryMethodName();
/**
* 返回此bean的构造函数参数值。
* <p>可以在bean工厂后处理期间修改返回的实例。
*
* @return ConstructorArgumentValues对象(从不{@code null})
*/
ConstructorArgumentValues getConstructorArgumentValues();
/**
* 返回是否有为此bean定义的构造函数参数值。
* @since 5.0.2
*/
default boolean hasConstructorArgumentValues() {
return !getConstructorArgumentValues().isEmpty();
}
/**
* 返回要应用到Bean的新实例的属性值。
* <p>可以在bean factory post-processing修改返回的实例。
*
* @return MutablePropertyValues对象(从不{<@@code> null})
*/
MutablePropertyValues getPropertyValues();
/**
* 返回是否有为此bean定义的属性值。
* @从5.0.2开始
*/
default boolean hasPropertyValues() {
return !getPropertyValues().isEmpty();
}
/**
* 设置初始化方法的名称。
* @5.1起
*/
void setInitMethodName(@Nullable String initMethodName);
/**
* 返回初始化方法的名称。
* @5.1起
*/
@Nullable
String getInitMethodName();
/**
* 设置destroy方法的名称。
* @5.1起
*/
void setDestroyMethodName(@Nullable String destroyMethodName);
/**
* 返回destroy方法的名称。
* @5.1起
*/
@Nullable
String getDestroyMethodName();
/**
* 设置此{@code BeanDefinition}的角色提示。
* 角色提示为框架和工具提供了特定{@code BeanDefinition}的角色和重要性的指示。
* @since 5.1
* @see #ROLE_APPLICATION
* @see #ROLE_SUPPORT
* @see #ROLE_INFRASTRUCTURE
*/
void setRole(int role);
/**
* 获取此{@code BeanDefinition}的角色提示。
* 角色提示为框架和工具提供了特定{@code BeanDefinition}的角色和重要性的指示。
*
* @see #ROLE_APPLICATION
* @see #ROLE_SUPPORT
* @see #ROLE_INFRASTRUCTURE
*/
int getRole();
/**
* 设置此bean定义的可读描述。
* @5.1起
*/
void setDescription(@Nullable String description);
/**
* 返回此bean定义的可读描述。
*
*/
@Nullable
String getDescription();
// Read-only attributes
/**
* 根据Bean类或其他特定的元数据,返回此Bean定义的可解析类型。
* <p>通常可以在运行时合并的bean定义中完全解决此问题,而不必在配置时定义实例上完全解决。
*
* @return 可解析类型(可能为{@link ResolvableType#NONE})@自5.2起
* @see ConfigurableBeanFactory#getMergedBeanDefinition
*/
ResolvableType getResolvableType();
/**
* 返回此<b> Singleton </ b>是否具有在所有调用中返回的单个共享实例。
*
* @see #SCOPE_SINGLETON
*/
boolean isSingleton();
/**
* 返回此是否为<b> Prototype </ b>,并为每个调用返回一个独立的实例。
* @since 3.0
* @see #SCOPE_PROTOTYPE
*/
boolean isPrototype();
/**
* 返回此bean是否为"抽象",即不打算实例化。
*/
boolean isAbstract();
/**
* 返回此bean定义来自的资源的描述(以在发生错误的情况下显示上下文)。
*/
@Nullable
String getResourceDescription();
/**
* 返回原始的BeanDefinition,如果没有,则返回{@code null}。
* 允许检索修饰的bean定义(如果有)。
* <p>请注意,此方法返回直接发起者。
* 遍历发起者链以找到用户定义的原始BeanDefinition。
*
*/
@Nullable
BeanDefinition getOriginatingBeanDefinition();
}
总结
BeanDefinition通过继承继承了AttributeAccessor描述了一个bean的配置信息,通过继承了BeanMetadataElement包含Bean的数据源(即Bean的Class对象)。
但是BeanDefinition不包含bean的名字。通过
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
definitionHolder将持有beanName。
Spring组件BeanDefinition 源码解析的更多相关文章
- Feign 系列(05)Spring Cloud OpenFeign 源码解析
Feign 系列(05)Spring Cloud OpenFeign 源码解析 [TOC] Spring Cloud 系列目录(https://www.cnblogs.com/binarylei/p/ ...
- spring boot @Value源码解析
Spring boot 的@Value只能用于bean中,在bean的实例化时,会给@Value的属性赋值:如下面的例子: @SpringBootApplication @Slf4j public c ...
- Spring Security 解析(七) —— Spring Security Oauth2 源码解析
Spring Security 解析(七) -- Spring Security Oauth2 源码解析 在学习Spring Cloud 时,遇到了授权服务oauth 相关内容时,总是一知半解,因 ...
- 异步任务spring @Async注解源码解析
1.引子 开启异步任务使用方法: 1).方法上加@Async注解 2).启动类或者配置类上@EnableAsync 2.源码解析 虽然spring5已经出来了,但是我们还是使用的spring4,本文就 ...
- Spring @Import注解源码解析
简介 Spring 3.0之前,创建Bean可以通过xml配置文件与扫描特定包下面的类来将类注入到Spring IOC容器内.而在Spring 3.0之后提供了JavaConfig的方式,也就是将IO ...
- Spring Security 访问控制 源码解析
上篇 Spring Security 登录校验 源码解析 分析了使用Spring Security时用户登录时验证并返回token过程,本篇分析下用户带token访问时,如何验证用户登录状态及权限问 ...
- .Net Core缓存组件(Redis)源码解析
上一篇文章已经介绍了MemoryCache,MemoryCache存储的数据类型是Object,也说了Redis支持五中数据类型的存储,但是微软的Redis缓存组件只实现了Hash类型的存储.在分析源 ...
- .Net Core缓存组件(MemoryCache)源码解析
一.介绍 由于CPU从内存中读取数据的速度比从磁盘读取快几个数量级,并且存在内存中,减小了数据库访问的压力,所以缓存几乎每个项目都会用到.一般常用的有MemoryCache.Redis.MemoryC ...
- Django 之 admin组件使用&源码解析
admin组件使用 Django 提供了基于 web 的管理工具. Django 自动管理工具是 django.contrib 的一部分.可以在项目的 settings.py 中的 INSTALLED ...
随机推荐
- Vue与React的区别
对已经了解的内容,做几点介绍,并不全面,后期会不断更新~ React与Vue都是组件化的开发框架,整体功能类似. 一.数据处理模式(单项 or 双向): React推崇单项数据流的处理模式,数据不可以 ...
- eslint报"Extra semicolon"错误的解决
手机赚钱怎么赚,给大家推荐一个手机赚钱APP汇总平台:手指乐(http://www.szhile.com/),辛苦搬砖之余用闲余时间动动手指,就可以日赚数百元 使用 vue-cli 构建的项目,模版是 ...
- leetcode-简单-栈-逆波兰表达式
根据逆波兰表示法,求表达式的值. 有效的运算符包括 +, -, *, / .每个运算对象可以是整数,也可以是另一个逆波兰表达式. 说明: 整数除法只保留整数部分. 给定逆波兰表达式总是有效的.换句话 ...
- SAP SD 销售中的借贷项凭证
SAP SD 销售中的借贷项凭证 SAP系统中,正常与客户的应收款都能通过销售订单来实现. 但实际操作中,常有收款后发现价格有误或其他原因需退款客户或补收客户货款的情况,或者客户需要少量的材料,但不能 ...
- Android9.0 Settings 修改踩坑记录
问题现象 上图展示的很清楚,当系统语言为中文时,PreferenceScreen 中的折叠项 summary 描述重复显示的 bug,系统语言为英文时正常. 修改历程 先搜索 当前显示了 字符串,还真 ...
- 剑指offer-面试题66-构建乘积数组-发散思维
/* 题目: 链接:https://www.nowcoder.com/questionTerminal/94a4d381a68b47b7a8bed86f2975db46 来源:牛客网 给定一个数组A[ ...
- opencv —— equalizeHist 直方图均衡化实现对比度增强
直方图均匀化简介 从这张未经处理的灰度图可以看出,其灰度集中在非常小的一个范围内.这就导致了图片的强弱对比不强烈. 直方图均衡化的目的,就是把原始的直方图变换为在整个灰度范围(0~255)内均匀分布的 ...
- 阿里云服务器Web Deploy配置和使用Visual Studio进行Web项目发布部署遇到的坑
阿里云的服务器一直闲着,烧着银子,当初花几千大洋开通,本想弄信息化的项目为所帮扶的贫困户脱贫助手,不想势单力薄,一直没有找到好的项目.最近大家都在众志成城抗击新肺疫情,于是又想能不能尽点自己的力量,于 ...
- Docker Stack 学习笔记
该文为<深入浅出Docker>的学习笔记,感谢查看,如有错误,欢迎指正 一.简介 Docker Stack 是为了解决大规模场景下的多服务部署和管理,提供了期望状态,滚动升级,简单易用,扩 ...
- LeetCode 面试题 02.07. 链表相交
题目链接:https://leetcode-cn.com/problems/intersection-of-two-linked-lists-lcci/ 给定两个(单向)链表,判定它们是否相交并返回交 ...