什么是BeanDefinition

在Java中,一切皆对象。在JDK中使用java.lang.Class来描述这个对象。

在Spring中,存在bean这样一个概念,那Spring又是怎么抽象bean这个概念,用什么类来描述bean这个对象呢?Spring使用BeanDefinition来描述bean

BeanDefinition

BeanDefinition继承了AttributeAccessorBeanMetadataElement接口。在Spring中充斥着大量的各种接口,每种接口都拥有不同的能力,某个类实现了某个接口,也就相应的拥有了某种能力。

AttributeAccessor

顾名思义,这是一个属性访问者,它提供了访问属性的能力。

BeanMetadataElement

BeanMetadataElement中只有一个方法,用来获取元数据元素的配置源对象:

public interface BeanMetadataElement {
@Nullable
Object getSource();
}

BeanDefinition

BeanDefinition接口是Spring对bean的抽象。

我们可以从源码中可以看出,Spring是怎么描述一个bean

public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {

	/**
* Scope identifier for the standard singleton scope: "singleton".
* <p>Note that extended bean factories might support further scopes.
*
* @see #setScope
*/
String SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON; /**
* Scope identifier for the standard prototype scope: "prototype".
* <p>Note that extended bean factories might support further scopes.
*
* @see #setScope
*/
String SCOPE_PROTOTYPE = ConfigurableBeanFactory.SCOPE_PROTOTYPE; /**
* Role hint indicating that a {@code BeanDefinition} is a major part
* of the application. Typically corresponds to a user-defined bean.
*/
int ROLE_APPLICATION = 0; /**
* Role hint indicating that a {@code BeanDefinition} is a supporting
* part of some larger configuration, typically an outer
* {@link org.springframework.beans.factory.parsing.ComponentDefinition}.
* {@code SUPPORT} beans are considered important enough to be aware
* of when looking more closely at a particular
* {@link org.springframework.beans.factory.parsing.ComponentDefinition},
* but not when looking at the overall configuration of an application.
*/
int ROLE_SUPPORT = 1; /**
* Role hint indicating that a {@code BeanDefinition} is providing an
* entirely background role and has no relevance to the end-user. This hint is
* used when registering beans that are completely part of the internal workings
* of a {@link org.springframework.beans.factory.parsing.ComponentDefinition}.
*/
int ROLE_INFRASTRUCTURE = 2; // Modifiable attributes /**
* Set the name of the parent definition of this bean definition, if any.
*/
void setParentName(@Nullable String parentName); /**
* Return the name of the parent definition of this bean definition, if any.
*/
@Nullable
String getParentName(); /**
* Specify the bean class name of this bean definition.
* <p>The class name can be modified during bean factory post-processing,
* typically replacing the original class name with a parsed variant of it.
*
* @see #setParentName
* @see #setFactoryBeanName
* @see #setFactoryMethodName
*/
void setBeanClassName(@Nullable String beanClassName); /**
* Return the current bean class name of this bean definition.
* <p>Note that this does not have to be the actual class name used at runtime, in
* case of a child definition overriding/inheriting the class name from its parent.
* Also, this may just be the class that a factory method is called on, or it may
* even be empty in case of a factory bean reference that a method is called on.
* Hence, do <i>not</i> consider this to be the definitive bean type at runtime but
* rather only use it for parsing purposes at the individual bean definition level.
*
* @see #getParentName()
* @see #getFactoryBeanName()
* @see #getFactoryMethodName()
*/
@Nullable
String getBeanClassName(); /**
* Override the target scope of this bean, specifying a new scope name.
*
* @see #SCOPE_SINGLETON
* @see #SCOPE_PROTOTYPE
*/
void setScope(@Nullable String scope); /**
* Return the name of the current target scope for this bean,
* or {@code null} if not known yet.
*/
@Nullable
String getScope(); /**
* Set whether this bean should be lazily initialized.
* <p>If {@code false}, the bean will get instantiated on startup by bean
* factories that perform eager initialization of singletons.
*/
void setLazyInit(boolean lazyInit); /**
* Return whether this bean should be lazily initialized, i.e. not
* eagerly instantiated on startup. Only applicable to a singleton bean.
*/
boolean isLazyInit(); /**
* Set the names of the beans that this bean depends on being initialized.
* The bean factory will guarantee that these beans get initialized first.
*/
void setDependsOn(@Nullable String... dependsOn); /**
* Return the bean names that this bean depends on.
*/
@Nullable
String[] getDependsOn(); /**
* Set whether this bean is a candidate for getting autowired into some other bean.
* <p>Note that this flag is designed to only affect type-based autowiring.
* It does not affect explicit references by name, which will get resolved even
* if the specified bean is not marked as an autowire candidate. As a consequence,
* autowiring by name will nevertheless inject a bean if the name matches.
*/
void setAutowireCandidate(boolean autowireCandidate); /**
* Return whether this bean is a candidate for getting autowired into some other bean.
*/
boolean isAutowireCandidate(); /**
* Set whether this bean is a primary autowire candidate.
* <p>If this value is {@code true} for exactly one bean among multiple
* matching candidates, it will serve as a tie-breaker.
*/
void setPrimary(boolean primary); /**
* Return whether this bean is a primary autowire candidate.
*/
boolean isPrimary(); /**
* Specify the factory bean to use, if any.
* This the name of the bean to call the specified factory method on.
*
* @see #setFactoryMethodName
*/
void setFactoryBeanName(@Nullable String factoryBeanName); /**
* Return the factory bean name, if any.
*/
@Nullable
String getFactoryBeanName(); /**
* Specify a factory method, if any. This method will be invoked with
* constructor arguments, or with no arguments if none are specified.
* The method will be invoked on the specified factory bean, if any,
* or otherwise as a static method on the local bean class.
*
* @see #setFactoryBeanName
* @see #setBeanClassName
*/
void setFactoryMethodName(@Nullable String factoryMethodName); /**
* Return a factory method, if any.
*/
@Nullable
String getFactoryMethodName(); /**
* Return the constructor argument values for this bean.
* <p>The returned instance can be modified during bean factory post-processing.
*
* @return the ConstructorArgumentValues object (never {@code null})
*/
ConstructorArgumentValues getConstructorArgumentValues(); /**
* Return if there are constructor argument values defined for this bean.
*
* @since 5.0.2
*/
default boolean hasConstructorArgumentValues() {
return !getConstructorArgumentValues().isEmpty();
} /**
* Return the property values to be applied to a new instance of the bean.
* <p>The returned instance can be modified during bean factory post-processing.
*
* @return the MutablePropertyValues object (never {@code null})
*/
MutablePropertyValues getPropertyValues(); /**
* Return if there are property values values defined for this bean.
*
* @since 5.0.2
*/
default boolean hasPropertyValues() {
return !getPropertyValues().isEmpty();
} /**
* Set the name of the initializer method.
*
* @since 5.1
*/
void setInitMethodName(@Nullable String initMethodName); /**
* Return the name of the initializer method.
*
* @since 5.1
*/
@Nullable
String getInitMethodName(); /**
* Set the name of the destroy method.
*
* @since 5.1
*/
void setDestroyMethodName(@Nullable String destroyMethodName); /**
* Return the name of the destroy method.
*
* @since 5.1
*/
@Nullable
String getDestroyMethodName(); /**
* Set the role hint for this {@code BeanDefinition}. The role hint
* provides the frameworks as well as tools with an indication of
* the role and importance of a particular {@code BeanDefinition}.
*
* @see #ROLE_APPLICATION
* @see #ROLE_SUPPORT
* @see #ROLE_INFRASTRUCTURE
* @since 5.1
*/
void setRole(int role); /**
* Get the role hint for this {@code BeanDefinition}. The role hint
* provides the frameworks as well as tools with an indication of
* the role and importance of a particular {@code BeanDefinition}.
*
* @see #ROLE_APPLICATION
* @see #ROLE_SUPPORT
* @see #ROLE_INFRASTRUCTURE
*/
int getRole(); /**
* Set a human-readable description of this bean definition.
*
* @since 5.1
*/
void setDescription(@Nullable String description); /**
* Return a human-readable description of this bean definition.
*/
@Nullable
String getDescription(); // Read-only attributes /**
* Return whether this a <b>Singleton</b>, with a single, shared instance
* returned on all calls.
*
* @see #SCOPE_SINGLETON
*/
boolean isSingleton(); /**
* Return whether this a <b>Prototype</b>, with an independent instance
* returned for each call.
*
* @see #SCOPE_PROTOTYPE
* @since 3.0
*/
boolean isPrototype(); /**
* Return whether this bean is "abstract", that is, not meant to be instantiated.
*/
boolean isAbstract(); /**
* Return a description of the resource that this bean definition
* came from (for the purpose of showing context in case of errors).
*/
@Nullable
String getResourceDescription(); /**
* Return the originating BeanDefinition, or {@code null} if none.
* Allows for retrieving the decorated bean definition, if any.
* <p>Note that this method returns the immediate originator. Iterate through the
* originator chain to find the original BeanDefinition as defined by the user.
*/
@Nullable
BeanDefinition getOriginatingBeanDefinition();
}

AnnotatedBeanDefinition

AnnotatedBeanDefinition 继承了BeanDefinition,拓展了BeanDefinition接口的能力:

BeanDefinition常见实现类

  • ChildBeanDefinition
  • RootBeanDefinition
  • GenericBeanDefinition
  • AnnotatedGenericBeanDefinition
  • ScannedGenericBeanDefinition

BeanDefinitionBuilder

BeanDefinitionBuilder是Builder模式的应用。通过这个类我们可以方便的构建BeanDefinition的实例对象。举个例子:

@Component
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor { @Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
BeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(OrderService.class)
//这里的属性名是根据setter方法
.addPropertyReference("dao", "orderDao")
.setInitMethodName("init")
.setScope(BeanDefinition.SCOPE_SINGLETON)
.getBeanDefinition(); registry.registerBeanDefinition("orderService", beanDefinition); } @Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
//do nothing
}
}

关于BeanDefinitionRegistryPostProcessor,这里先简单介绍一下,详细的我们后面再说。

BeanDefinitionRegistryPostProcessor继承了BeanFactoryPostProcessor接口,同时又增加了一个新的方法BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry,该方法允许程序员通过代码编码的方式手动往程序中注册BeanDefinition

实例中的具体程序已上传到github:https://github.com/shenjianeng/spring-code-study


欢迎关注公众号:

使用 BeanDefinition 描述 Spring Bean的更多相关文章

  1. spring bean的重新加载

    架构体系 在谈spring bean的重新加载前,首先我们来看看spring ioc容器. spring ioc容器主要功能是完成对bean的创建.依赖注入和管理等功能,而这些功能的实现是有下面几个组 ...

  2. 0003 - 基于xml的Spring Bean 的创建过程

    一.目录 前言 创建 Bean 容器 加载 Bean 定义 创建 Bean Spring Bean 创建过程中的设计模式 总结 二.前言 2.1 Spring 使用配置 ApplicationCont ...

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

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

  4. Spring之2:Spring Bean动态注册、删除

    IoC容器的初始化包括BeanDefinition的Resource定位.载入和注册这三个基本的过程. 一.Resource定位.BeanDefinition的资源定位有resourceLoader通 ...

  5. Spring Bean的一生

    Spring Bean的一生 When you work directly in Java, you can do anything you like with your objects and do ...

  6. 【转】spring bean 卸载

    spring bean 卸载起因: 群里的一个朋友问到: 关于配置destory-method, springboot中 yml如何指定 首先介绍 bean卸载的三种形式 自定义destory-met ...

  7. 【Spring】IoC容器 - Spring Bean作用域Scope(含SpringCloud中的RefreshScope )

    前言 上一章学习了[依赖来源],本章主要讨论SpringBean的作用域,我们这里讨论的Bean的作用域,很大程度都是默认只讨论依赖来源为[Spring BeanDefinition]的作用域,因为在 ...

  8. 大厂高频面试题Spring Bean生命周期最详解

    Spring作为当前Java最流行.最强大的轻量级框架.Spring Bean的生命周期也是面试高频题,了解Spring Bean周期也能更好地帮助我们解决日常开发中的问题.程序员应该都知道Sprin ...

  9. Spring8:一些常用的Spring Bean扩展接口

    前言 Spring是一款非常强大的框架,可以说是几乎所有的企业级Java项目使用了Spring,而Bean又是Spring框架的核心. Spring框架运用了非常多的设计模式,从整体上看,它的设计严格 ...

随机推荐

  1. UVA-10004-Bicoloring二分图染色

    题意:给一张图,判断是不是二分图: 自己一开始不知道是二分图染色,理解的是任意三点不能互相连接 可能以后遇到这样的模型,可以往二分图想: 首先怎么判定一个图是否为二分图 从其中一个定点开始,将跟它邻接 ...

  2. Java连载27-有返回值的方法注意点

    一.方法注意点 (1)方法的调用不一定再main方法中,可以在其他方法中进行调用,只要是程序执行到的位置,都可以去调用其他方法. (2)方法调用的时候,实参和形参要求个数对应相同,数据类型对应相同,方 ...

  3. 调度系统Airflow的第一个DAG

    Airflow的第一个DAG 考虑了很久,要不要记录airflow相关的东西, 应该怎么记录. 官方文档已经有比较详细的介绍了,还有各种博客,我需要有一份自己的笔记吗? 答案就从本文开始了. 本文将从 ...

  4. Java并发编程(一):进程和线程之由来

    转自:http://www.cnblogs.com/dolphin0520/p/3910667.html 在前面,已经介绍了Java的基础知识,现在我们来讨论一点稍微难一点的问题:Java并发编程.当 ...

  5. 【LeetCode】[0002] 【两数之和】

    题目描述 思路分析 测试用例 Java代码 代码链接 题目描述 给出两个非空 的链表用来表示两个非负的整数.其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字.如果 ...

  6. git合并出现冲突

    git合并出现冲突:Your local changes to the following files would be overwritten by merge:Please, commit you ...

  7. Maven学习归纳(一)——简单的环境配置入门

    一.Maven的基本概念 Maven是基于项目对象模型(POM),可以通过一小段描述信息来管理项目的编译,测试,构建,报告和文档的软件项目管理工具和解决依赖关系的工具. 1.1 项目的构建 项目的构建 ...

  8. openlivewriter安装配置

    一.前言 最近工作比较忙,同时也在构思下面我应该写哪方面的文章.上一篇文章,我直接在博客园管理后台自带的编辑器写的,确实比较麻烦,于是我就打算使用官方推荐的客户端“Open Live Writer”. ...

  9. iOS 13 绕过锁屏密码漏洞

    iOS 13 很快就要发布了,在未正式发布之前,西班牙的安全研究员 Jose Rodriguez 公开了一个漏洞,能够查绕过锁屏密码查看通讯录.照片.短信. 在 iOS 设备上,当屏幕锁定时,用户无法 ...

  10. NGUI_基础入门学习

    目录 1. Control Widgets 控制部件2. Anchors 锚3. Interaction 交互4. Menu 菜单5. Controller Input 控制器的输入6. Lights ...