Spring 源码分析(二)——GenericBeanDefinition 分析

这篇具有很好参考价值的文章主要介绍了Spring 源码分析(二)——GenericBeanDefinition 分析。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

BeanDefinition 中存储着 Bean 的定义信息,它具有属性值、构造函数参数值以及具体实现 Bean 提供的进一步信息,在学习 SpringBean 初始化流程之前,还是非常有必要先了解一下 BeanDefinition

一、注册 Bean 示例

首先,本文先举一个使用 BeanDefinition 创建 Bean 的小例子:

import com.nineya.spring.entity.Post;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.PropertyValue;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.support.GenericBeanDefinition;

import java.util.ArrayList;
import java.util.List;

public class SpringMain {
    public static void main(String[] args) {
        // 创建bean工厂
        DefaultListableBeanFactory context = new DefaultListableBeanFactory();

        //构造bean定义
        GenericBeanDefinition gbd = new GenericBeanDefinition();
        gbd.setBeanClass(Post.class);

        // 设置属性
        List<PropertyValue> propertyValues = new ArrayList<>();
        propertyValues.add(new PropertyValue("id", 123L));
        propertyValues.add(new PropertyValue("title", "title"));
        gbd.setPropertyValues(new MutablePropertyValues(propertyValues));

        //注册到环境上下文
        context.registerBeanDefinition("post", gbd);

        // 通过class取得bean
        Post post = context.getBean(Post.class);
        System.out.println(post + " : " + post.hashCode());

        // 通过名称取得bean
        post = (Post) context.getBean("post");
        System.out.println(post + " : " + post.hashCode());
    }
}

执行结果输出:

Post(id=123, title=title, categories=null, tags=null, content=null) : 1339167804
Post(id=123, title=title, categories=null, tags=null, content=null) : 1339167804

二、GenericBeanDefinition 结构

GenericBeanDefinition 类继承关系图如下:

Spring 源码分析(二)——GenericBeanDefinition 分析

逐个对 GenericBeanDefinition 继承的类/接口进行分析:

BeanMetadataElement 接口: BeanMetadataElement 提供了获取数据源的方式,也就是可以指导 Bean 是来自哪个类,由携带配置源对象的 Bean 元数据元素实现的接口。

接口 说明
Object getSource() 返回此元数据元素的配置源

AttributeAccessorSupport 抽象类: 支持 AttributeAccessor 属性存取接口,内部使用的 LinkedHashMap,提供
所有方法的基本实现,由子类扩展。

接口 说明
void setAttribute(String name, @Nullable Object value) 设置属性
Object getAttribute(String name) 取得属性
Object removeAttribute(String name) 删除并返回属性
boolean hasAttribute(String name) 判断属性是否存在
String[] attributeNames() 取得所有属性的名称

以上这两个接口的实现皆与 GenericBeanDefinition 无关联,这是公共的基础类。

BeanMetadataAttributeAccessor 类: 将元数据参数封装为 BeanMetadataAttribute,用于 Bean 的元数据和属性上下文操作的实现类。

接口 说明
void setSource(@Nullable Object source) 为这个元数据元素设置配置源
void addMetadataAttribute(BeanMetadataAttribute attribute) 将给定的BeanMetadataAttribute添加到该访问器的属性集
BeanMetadataAttribute getMetadataAttribute(String name) 在这个访问器的属性集中查找给定的BeanMetadataAttribute

BeanDefinition 接口

接口 说明
void setParentName(@Nullable String parentName) 设置此 bean 定义的父定义的名称(如果有的话)
String getParentName() 返回此 bean 定义的父定义的名称(如果有的话)
void setBeanClassName(@Nullable String beanClassName) 指定此 bean 定义的 bean 类名。类名可以在 bean 工厂后期处理期间修改,通常是用解析后的类名替换原来的类名
String getBeanClassName() 返回此 bean 定义的当前bean类名称。注意,这并不一定是运行时使用的实际类名,例如子定义覆盖/继承其父类名。
void setScope(@Nullable String scope) 重写此 bean 的目标范围,指定一个新的范围名
String getScope() 返回此 bean 的当前目标作用域的名称
void setLazyInit(boolean lazyInit) 设置该 bean 是否应该延迟初始化
boolean isLazyInit() 返回该 bean 是否应该延迟初始化,即在启动时实例化
void setDependsOn(@Nullable String… dependsOn) 设置此 bean 所依赖的初始化 bean 的名称, bean 工厂将保证这些 bean 首先被初始化
String[] getDependsOn() 返回此 bean 所依赖的初始化 bean 的名称
void setAutowireCandidate(boolean autowireCandidate) 设置该 bean 是否为自动连接到其他 bean 的候选 bean
boolean isAutowireCandidate() 返回该 bean 是否是自动连接到其他 bean 的候选 bean
void setPrimary(boolean primary) 设置此 bean 是否为主要自动装配候选
boolean isPrimary() 返回此 bean 是否是自动装配的主要候选
void setFactoryBeanName(@Nullable String factoryBeanName) 指定要使用的工厂 bean 名称
String getFactoryBeanName() 返回工厂 bean 名称(如果有的话)
void setFactoryMethodName(@Nullable String factoryMethodName) 指定一个工厂方法,该方法将使用构造函数参数调用,如果没有指定参数,则不使用参数调用。该方法将在指定的工厂 bean 上调用,或者作为本地 bean 类上的静态方法调用。
String getFactoryMethodName() 返回一个工厂方法
ConstructorArgumentValues getConstructorArgumentValues() 返回此 bean 的构造函数参数值
boolean hasConstructorArgumentValues() 判断此 bean 是否定义了构造函数参数值
MutablePropertyValues getPropertyValues() 返回应用于 bean 的新实例的属性值
boolean hasPropertyValues() 判断此 bean 是否定义了属性值
void setInitMethodName(@Nullable String initMethodName) 设置初始化器方法的名称
String getInitMethodName() 返回初始化方法的名称
void setDestroyMethodName(@Nullable String destroyMethodName) 设置销毁方法的名称
String getDestroyMethodName() 返回销毁方法的名称
void setRole(int role) 为这个 BeanDefinition 设置角色提示
int getRole() 获取这个 BeanDefinition 的角色提示
void setDescription(@Nullable String description) 设置此 bean 定义的人类可读的描述
String getDescription() 取得此 bean 定义的人类可读的描述
ResolvableType getResolvableType() 根据 bean 类或其他特定元数据,返回此 bean 定义的可解析类型
boolean isSingleton() 判断此 bean 是否是单例
boolean isPrototype() 判断此 bean 是否是原型
boolean isAbstract() 返回此 bean 是否是“抽象的”,即不需要实例化
String getResourceDescription() 返回此 bean 定义所来自的资源的描述(以便在出现错误时显示上下文)
BeanDefinition getOriginatingBeanDefinition() 返回原始的 BeanDefinition

AbstractBeanDefinition 抽象类: AbstractBeanDefinition 是具体的、BeanDefinition 类的基类,分解出 GenericBeanDefinitionRootBeanDefinitionChildBeanDefinition 的公共属性和逻辑。文章来源地址https://www.toymoban.com/news/detail-410451.html

接口 说明
void overrideFrom(BeanDefinition other) 使用给定 BeanDefinition 定义重新当前 BeanDefinition 中的设置
void applyDefaults(BeanDefinitionDefaults defaults) 将提供的默认值应用到此 bean
void setBeanClass(@Nullable Class<?> beanClass) 为这个 bean 指定类
Class<?> getBeanClass() throws IllegalStateException 返回 bean 定义的指定类
boolean hasBeanClass() 返回该定义是否指定了 bean
Class<?> resolveBeanClass(@Nullable ClassLoader classLoader) 确定被包装bean的类,如果需要,从指定的类名解析它
void setAbstract(boolean abstractFlag) 默认为“false”。指定 true 告诉 bean 工厂在任何情况下都不要尝试实例化 bean
Boolean getLazyInit() 返回该 bean 是否应该延迟初始化
void setAutowireMode(int autowireMode) 设置自动装配模式。这决定是否会发生 bean 引用的自动检测和设置
int getAutowireMode() 返回 bean 定义中指定的自动装配模式
int getResolvedAutowireMode() 返回已解析的自动装配代码
void setDependencyCheck(int dependencyCheck) 设置依赖项检查代码
int getDependencyCheck() 返回依赖项检查代码
addQualifier(AutowireCandidateQualifier qualifier) 注册一个用于自动装配候选解析的限定符,以限定符的类型名称为键值
boolean hasQualifier(String typeName) 返回此 bean 是否具有指定的限定符
AutowireCandidateQualifier getQualifier(String typeName) 返回映射到所提供类型名称的限定符
Set<AutowireCandidateQualifier> getQualifiers() 返回所有已注册的限定符
void copyQualifiersFrom(AbstractBeanDefinition source) 将所提供的 AbstractBeanDefinition 中的限定符复制到当前 BeanDefinition
public void setInstanceSupplier(@Nullable Supplier<?> instanceSupplier) 指定用于创建 bean 实例的回调,作为声明式指定工厂方法的替代方法
Supplier<?> getInstanceSupplier() 返回用于创建 bean 实例的回调(如果有的话)
void setNonPublicAccessAllowed(boolean nonPublicAccessAllowed) 指定是否允许访问非公共构造函数和方法,如果外部化元数据指向它们
boolean isNonPublicAccessAllowed() 返回是否允许访问非公共构造函数和方法
void setLenientConstructorResolution(boolean lenientConstructorResolution) 指定是否在宽限模式下解析构造函数
boolean isLenientConstructorResolution() 返回以宽松模式还是严格模式解析构造函数
void setConstructorArgumentValues(ConstructorArgumentValues constructorArgumentValues) 为这个 bean 指定构造函数参数值
void setPropertyValues(MutablePropertyValues propertyValues) 指定此 bean 的属性值(如果有的话)
void setMethodOverrides(MethodOverrides methodOverrides) bean 指定方法重写(如果有的话)
MethodOverrides getMethodOverrides() 返回 IoC 容器要覆盖的方法的信息。如果没有方法重写,该参数将为空。
boolean hasMethodOverrides() 是否为此 bean 定义了方法重写
void setEnforceInitMethod(boolean enforceInitMethod) 指定配置的初始化方法是否为默认值
boolean isEnforceInitMethod() 指示配置的初始化方法是否为默认值
void setEnforceDestroyMethod(boolean enforceDestroyMethod) 设置配置的销毁方法是否为默认值
boolean isEnforceDestroyMethod() 指定配置的销毁方法是否为默认值
void setSynthetic(boolean synthetic) 设置这个 bean 定义是否是“合成的”
boolean isSynthetic() 返回此 bean 定义是否是“合成的”,即不是由应用程序本身定义的
void setResource(@Nullable Resource resource) 设置此 bean 定义所来自的资源(以便在出现错误时显示上下文)
setResourceDescription(@Nullable String resourceDescription) 设置此 bean 定义所来自的资源的描述(以便在出现错误时显示上下文)
void setOriginatingBeanDefinition(BeanDefinition originatingBd) 如果有的话,设置原始的(例如装饰过的) BeanDefinition
void validate() throws BeanDefinitionValidationException 验证这个 BeanDefinition
void prepareMethodOverrides() throws BeanDefinitionValidationException 验证并准备为此 bean 定义的方法重写。检查具有指定名称的方法是否存在
void prepareMethodOverride(MethodOverride mo) throws BeanDefinitionValidationException 验证并准备给定的方法重写。检查具有指定名称的方法是否存在,如果没有找到则将其标记为未重载

到了这里,关于Spring 源码分析(二)——GenericBeanDefinition 分析的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Spring专题】Spring之Bean的生命周期源码解析——阶段一(扫描生成BeanDefinition)

    由于Spring源码分析是一个前后联系比较强的过程,而且这边分析,也是按照代码顺序讲解的,所以不了解前置知识的情况下,大概率没办法看懂当前的内容。所以,特别推荐看看我前面的文章(自上而下次序): Spring底层核心原理解析——引导篇【学习难度: ★★☆☆☆ 】

    2024年02月13日
    浏览(43)
  • Spring之BeanDefinition(二)

    Spring的任何源码都绕不开bean的生命周期,首先来看一下bean和对象的区别: 作为一个普通对象来说,一个类编译生成xx.class之后,通过构造方法(具体类,非抽象和接口)创建出来一个对象; 作为Spring的bean来说,是经历过完成的bean的生命周期的,其中包含了上面创建对象这

    2024年02月15日
    浏览(29)
  • spring启动流程 (3) BeanDefinition详解

    BeanDefinition在Spring初始化阶段保存Bean的元数据信息,包括Class名称、Scope、构造方法参数、属性值等信息,本文将介绍一下BeanDefinition接口、重要的实现类,以及在Spring中的使用示例。 用于描述了一个Bean实例,该Bean实例具有属性、构造方法参数以及由具体实现提供的其他信息

    2024年02月12日
    浏览(40)
  • Spring IOC 之加载 BeanDefinition

    🎬作者简介:大家好,我是小徐🥇 ☁️博客首页:CSDN主页 小徐的博客 🌄每日一句: 好学而不勤非真好学者 前面的文章我们已经对IOC之Spring统一资源加载策略有了一定的了解,本文我们将探讨Spring IOC 加载 BeanDefinition的整个过程。 我们先先看一段熟悉的代码: 这段代码是

    2024年01月17日
    浏览(38)
  • Spring高手之路12——BeanDefinitionRegistry与BeanDefinition合并解析

       BeanDefinitionRegistry 是一个非常重要的接口,存在于 Spring 的 org.springframework.beans.factory.support 包中,它是 Spring 中注册和管理 BeanDefinition 的核心组件。   让我们回顾一下上一篇说的 BeanDefinition 。在 Spring 中,一个 Bean 就是一个被 Spring 管理的对象,而一个 BeanDefinition 则是

    2024年02月13日
    浏览(40)
  • Spring高手之路11——BeanDefinition解密:构建和管理Spring Beans的基石

       BeanDefinition 是 Spring 中一个非常重要的概念,它包含了 Spring 容器用于创建、配置 Bean 所需的所有信息。理解 BeanDefinition 可以帮助我们深入掌握 Spring 的内部工作机制。 首先,让我们来对 BeanDefinition 有一个整体的认识。   对于理解 Spring 框架的概念和组件, Spring 的官方

    2024年02月15日
    浏览(47)
  • Spring源码分析(五) 事务全流程分析

    @Transactional 注解的属性信息 name 当在配置文件中有多个 TransactionManager , 可以用该属性指定选择哪个事务管理器 propagation 事务的传播行为,默认值为 REQUIRED。 isolation 事务的隔离度,默认值采用 DEFAULT。 timeout 事务的超时时间,默认值为-1。如果超过该时间限制但事务还没有完

    2024年02月07日
    浏览(34)
  • 【spring源码分析】@Conditional的使用以及分析

    @Conditional 一、基本信息 二、注解描述 三、注解源码 四、主要功能 五、最佳实践 在@Bean上使用 在@Configuration上使用 自定义组合注解 六、时序图 七、源码分析 八、注意事项 九、总结 最佳实践总结 源码分析总结 一、基本信息 转载自github,在此作为个人备份(https://blog.csdn.

    2024年01月21日
    浏览(89)
  • Spring IOC 源码分析

    ​ IoC (Inversion of control ) 控制反转。它是一种思想不是一个技术实现。描述的是: Java 开发领域对象的创建以及管理的问题。 例如:现有类 A 依赖于类 B 。传统的开发方式 :往往是在类 A 中手动通过 new 来 new 一个 B 的对象出来使用 IoC 思想的开发方式 :不通过 ne

    2024年02月02日
    浏览(44)
  • Spring AOP 源码分析

    【阅读前提】: 需了解 AOP 注解开发流程:链接 在配置类中添加注解 @EnableAspectJAutoProxy ,便开启了 AOP (面向切面编程) 功能。此注解也是了解 AOP 源码的入口。 【1】 @EnableAspectJAutoProxy 是什么?我们进入注解,查看其源码如下:发现调用 EnableAspectJAutoProxy 类,同时使用 @

    2024年01月16日
    浏览(33)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包