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

【Spring生命周期】Bean元信息配置阶段

引言

本系列将详细讲解Spring生命周期的13个阶段,从源码角度帮助我们更好的理解Spring框架和bean生命周期全流程

Bean信息定义4种方式

  • API的方式
  • Xml文件方式
  • properties文件的方式
  • 注解的方式

在 Spring 框架中,Bean 元信息配置阶段是整个 Bean 生命周期的起始阶段,主要负责定义和描述 Bean 的各种属性和行为,为后续 Bean 的创建、初始化和使用奠定基础。下面将详细介绍 Bean 元信息配置阶段的相关内容,包括配置方式、核心元素及配置过程。

BeanDefinition接口:bean定义信息接口

表示bean定义信息的接口,里面定义了一些获取bean定义配置信息的各种方法,来看一下源码:

public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {

    /**
     * 设置此bean的父bean名称(对应xml中bean元素的parent属性)
     */
    void setParentName(@Nullable String parentName);

    /**
     * 返回此bean定义时指定的父bean的名称
     */
    @Nullable
    String getParentName();

    /**
     * 指定此bean定义的bean类名(对应xml中bean元素的class属性)
     */
    void setBeanClassName(@Nullable String beanClassName);

    /**
     * 返回此bean定义的当前bean类名
     * 注意,如果子定义重写/继承其父类的类名,则这不一定是运行时使用的实际类名。此外,这可能只是调用工厂方法的类,或者在调用方法的工厂bean引用的情况下,它甚至可能是空的。因此,不要认为这是运行时的最终bean类型,而只将其用于单个bean定义级别的解析目的。
     */
    @Nullable
    String getBeanClassName();

    /**
     * 设置此bean的生命周期,如:singleton、prototype(对应xml中bean元素的scope属性)
     */
    void setScope(@Nullable String scope);

    /**
     * 返回此bean的生命周期,如:singleton、prototype
     */
    @Nullable
    String getScope();

    /**
     * 设置是否应延迟初始化此bean(对应xml中bean元素的lazy属性)
     */
    void setLazyInit(boolean lazyInit);

    /**
     * 返回是否应延迟初始化此bean,只对单例bean有效
     */
    boolean isLazyInit();

    /**
     * 设置此bean依赖于初始化的bean的名称,bean工厂将保证dependsOn指定的bean会在当前bean初始化之前先初始化好
     */
    void setDependsOn(@Nullable String... dependsOn);

    /**
     * 返回此bean所依赖的bean名称
     */
    @Nullable
    String[] getDependsOn();

    /**
     * 设置此bean是否作为其他bean自动注入时的候选者
     * autowireCandidate
     */
    void setAutowireCandidate(boolean autowireCandidate);

    /**
     * 返回此bean是否作为其他bean自动注入时的候选者
     */
    boolean isAutowireCandidate();

    /**
     * 设置此bean是否为自动注入的主要候选者
     * primary:是否为主要候选者
     */
    void setPrimary(boolean primary);

    /**
     * 返回此bean是否作为自动注入的主要候选者
     */
    boolean isPrimary();

    /**
     * 指定要使用的工厂bean(如果有)。这是要对其调用指定工厂方法的bean的名称。
     * factoryBeanName:工厂bean名称
     */
    void setFactoryBeanName(@Nullable String factoryBeanName);

    /**
     * 返回工厂bean名称(如果有)(对应xml中bean元素的factory-bean属性)
     */
    @Nullable
    String getFactoryBeanName();

    /**
     * 指定工厂方法(如果有)。此方法将使用构造函数参数调用,如果未指定任何参数,则不使用任何参数调用。该方法将在指定的工厂bean(如果有的话)上调用,或者作为本地bean类上的静态方法调用。
     * factoryMethodName:工厂方法名称
     */
    void setFactoryMethodName(@Nullable String factoryMethodName);

    /**
     * 返回工厂方法名称(对应xml中bean的factory-method属性)
     */
    @Nullable
    String getFactoryMethodName();

    /**
     * 返回此bean的构造函数参数值
     */
    ConstructorArgumentValues getConstructorArgumentValues();

    /**
     * 是否有构造器参数值设置信息(对应xml中bean元素的<constructor-arg />子元素)
     */
    default boolean hasConstructorArgumentValues() {
        return !getConstructorArgumentValues().isEmpty();
    }

    /**
     * 获取bean定义是配置的属性值设置信息
     */
    MutablePropertyValues getPropertyValues();

    /**
     * 这个bean定义中是否有属性设置信息(对应xml中bean元素的<property />子元素)
     */
    default boolean hasPropertyValues() {
        return !getPropertyValues().isEmpty();
    }

    /**
     * 设置bean初始化方法名称
     */
    void setInitMethodName(@Nullable String initMethodName);

    /**
     * bean初始化方法名称
     */
    @Nullable
    String getInitMethodName();

    /**
     * 设置bean销毁方法的名称
     */
    void setDestroyMethodName(@Nullable String destroyMethodName);

    /**
     * bean销毁的方法名称
     */
    @Nullable
    String getDestroyMethodName();

    /**
     * 设置bean的role信息
     */
    void setRole(int role);

    /**
     * bean定义的role信息
     */
    int getRole();

    /**
     * 设置bean描述信息
     */
    void setDescription(@Nullable String description);

    /**
     * bean描述信息
     */
    @Nullable
    String getDescription();

    /**
     * bean类型解析器
     */
    ResolvableType getResolvableType();

    /**
     * 是否是单例的bean
     */
    boolean isSingleton();

    /**
     * 是否是多列的bean
     */
    boolean isPrototype();

    /**
     * 对应xml中bean元素的abstract属性,用来指定是否是抽象的
     */
    boolean isAbstract();

    /**
     * 返回此bean定义来自的资源的描述(以便在出现错误时显示上下文)
     */
    @Nullable
    String getResourceDescription();

    @Nullable
    BeanDefinition getOriginatingBeanDefinition();

}

BeanDefinition接口上面还继承了2个接口:

  • AttributeAccessor
  • BeanMetadataElement

AttributeAccessor接口:属性访问接口

public interface AttributeAccessor {

    /**
     * 设置属性->值
     */
    void setAttribute(String name, @Nullable Object value);

    /**
     * 获取某个属性对应的值
     */
    @Nullable
    Object getAttribute(String name);

    /**
     * 移除某个属性
     */
    @Nullable
    Object removeAttribute(String name);

    /**
     * 是否包含某个属性
     */
    boolean hasAttribute(String name);

    /**
     * 返回所有的属性名称
     */
    String[] attributeNames();

}

这个接口相当于key->value数据结构的一种操作,BeanDefinition继承这个,内部实际上是使用了LinkedHashMap来实现这个接口中的所有方法,通常我们通过这些方法来保存BeanDefinition定义过程中产生的一些附加信息。

BeanMetadataElement接口

public interface BeanMetadataElement {

    @Nullable
    default Object getSource() {
        return null;
    }

}

BeanDefinition继承这个接口,getSource返回BeanDefinition定义的来源,比如我们通过xml定义BeanDefinition的,此时getSource就表示定义bean的xml资源;若我们通过api的方式定义BeanDefinition,我们可以将source设置为定义BeanDefinition时所在的类,出错时,可以根据这个来源方便排错。

RootBeanDefinition类:表示根bean定义信息

通常bean中没有父bean的就使用这种表示

ChildBeanDefinition类:表示子bean定义信息

如果需要指定父bean的,可以使用ChildBeanDefinition来定义子bean的配置信息,里面有个parentName属性,用来指定父bean的名称。

GenericBeanDefinition类:通用的bean定义信息

既可以表示没有父bean的bean配置信息,也可以表示有父bean的子bean配置信息,这个类里面也有parentName属性,用来指定父bean的名称。

ConfigurationClassBeanDefinition类:表示通过配置类中@Bean方法定义bean信息

可以通过配置类中使用@Bean来标注一些方法,通过这些方法来定义bean,这些方法配置的bean信息最后会转换为ConfigurationClassBeanDefinition类型的对象

相关文章:

  • Python Selenium自动化操作详解:从入门到实战
  • JavaScript中的函数基础知识
  • win10本地部署deepseek-r1步骤
  • 用户的声音 | 文档结构化信息提取方案测评:LLM、开源模型部署与云端API,谁是合适选择?
  • 在 Vue 项目中,为什么要在列表组件中写 key,其作用是什么?
  • 什么是幂等性?
  • 【SpringMVC】Controller的多种方式接收请求参数
  • DeepSeek模型快速部署教程-搭建自己的DeepSeek
  • 在Unity中用简单工厂模式模拟原神中的元素反应
  • DeepSeek服务器繁忙 多种方式继续优雅的使用它
  • MySQL 的存储引擎有哪些?它们之间有什么区别? MySQL InnoDB 引擎中的聚簇索引和非聚簇索引有什么区别? MySQL 的索引类型有哪些?
  • 框架篇 - Hearth ArcGIS 框架扩展(DryIoC、Options、Nlog...)
  • XCP协议
  • 【刷题】leetcode
  • var、let、const区别
  • 项目中分库分表的分布式ID如何生成
  • 数据结构与算法-搜索-bfs(floodfill and 最短路):池塘计数,城堡问题,山峰和山谷,迷宫问题,武士分度的牛,抓住那头牛
  • 深入理解 QObject的作用
  • 【JavaEE进阶】#{}和${}
  • 【Pandas】pandas Series reindex_like
  • 工程院院士葛世荣获聘任为江西理工大学校长
  • “降息潮”延续!存款利率全面迈向“1时代”
  • 中国天主教组织发贺电对新教皇当选表示祝贺
  • 中华人民共和国和俄罗斯联邦在纪念中国人民抗日战争、苏联伟大卫国战争胜利和联合国成立80周年之际关于进一步深化中俄新时代全面战略协作伙伴关系的联合声明
  • 教育部、国家发改委联合启动实施教师教育能力提升工程
  • 民生访谈|今年上海还有哪些重要演出展览?场地配套如何更给力?