当前位置: 首页 > article >正文

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 类继承关系图如下:

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 的公共属性和逻辑。

接口说明
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验证并准备给定的方法重写。检查具有指定名称的方法是否存在,如果没有找到则将其标记为未重载

http://www.kler.cn/a/9878.html

相关文章:

  • 基于微信小程序的农场管理系统的设计与实现,LW+源码+讲解
  • qt QKeySequence详解
  • uniCloud云对象调用第三方接口,根据IP获取用户归属地的免费API接口,亲测可用
  • 数据结构-集合
  • P8680 [蓝桥杯 2019 省 B] 特别数的和
  • MySQ怎么使用语法介绍(详细)
  • Java知识点学习(第6天)
  • SQL Server的日志传送
  • 高效管理 Linux 进程:如何后台执行程序、查看进程、终止任务
  • 机器学习-问答题准备(英文)-更新中
  • 用JavaScript实现最大子数组和的动态规划算法
  • Msray-Plus采集工具让您的市场营销更加简单,让您的营销成果更加显著
  • NumPy 秘籍中文第二版:十二、使用 NumPy 进行探索性和预测性数据分析
  • 吐血奉献精心整理的一大波数据集
  • 【C#】程序和sql速度对比
  • 【消息队列】聊一下生产者消息发送流程
  • 7nm舱泊一体SoC的新玩家
  • 三大前端框架Vue, Angular, React
  • 月薪过 3w 的 软件测试工程师 都是怎么做到的?
  • Spring Security 6.0系列【16】授权篇之访问控制
  • 国网B接口调阅实时视频规范解读和代码示例分析
  • 代码随想录_二叉树_leetcode236
  • Java阶段一Day19
  • 值栈的概念和作用是什么?
  • 关于iptables封禁国外IP方法
  • 多模态模型技术综述