Spring5源码分析(013)——IoC篇之解析bean标签:BeanDefinition 和 AbstractBeanDefinition

2021-03-31 12:28

阅读:424

标签:tor   return   data   完全   rop   clone   官方文档   placed   generic   

注:《Spring5源码分析》汇总可参考:Spring5源码分析(002)——博客汇总


  前面已经提到, bean 标签配置的相关属性都是 BeanDefinition 来承载,其内部对此提供意义对应的相关属性,本篇单独对 BeanDefinition 进行简要说明,以便对此有一个整体的认知。目录结构如下:

  • 1、BeanDefinition
  • 2、BeanDefinition 体系
    • 2.1、BeanDefinition 的父接口
    • 2.2、BeanDefinition 的子类
    • 2.3、抽象子类 AbstractBeanDefinition 的属性
  • 3、总结
  • 4、参考

 

1、BeanDefinition

  org.springframework.beans.factory.config.BeanDefinition 描述了一个 bean 实例,包括属性值、构造函数参数值等,由具体实现提供更进一步的信息。

  这只是一个最小的接口:主要目的是允许 BeanFactoryPostProcessor 访问内部属性(introspector)并且修改属性值和其他 bean 元数据。

  BeanDefinition 内部定义如下:

/**
 * A BeanDefinition describes a bean instance, which has property values,
 * constructor argument values, and further information supplied by
 * concrete implementations.
 * 

BeanDefinition 描述了一个 bean 实例,包括属性值、构造函数参数值,由具体实现提供更进一步的信息。 *

This is just a minimal interface: The main intention is to allow a * {

@link BeanFactoryPostProcessor} to introspect and modify property values * and other bean metadata. *

这只是一个最小的接口:主要目的是允许 BeanFactoryPostProcessor 访问 * 内部属性(introspector)并且修改属性值和其他 bean 元数据。

*/ public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement { /** * Scope identifier for the standard singleton scope: {@value}. *

Note that extended bean factories might support further scopes. *

@see #setScope * @see ConfigurableBeanFactory#SCOPE_SINGLETON */ String SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON; /** * Scope identifier for the standard prototype scope: {@value}. *

Note that extended bean factories might support further scopes. *

@see #setScope * @see ConfigurableBeanFactory#SCOPE_PROTOTYPE */ String SCOPE_PROTOTYPE = ConfigurableBeanFactory.SCOPE_PROTOTYPE; int ROLE_APPLICATION = 0; int ROLE_SUPPORT = 1; int ROLE_INFRASTRUCTURE = 2; // Modifiable attributes void setParentName(@Nullable String parentName); @Nullable String getParentName(); void setBeanClassName(@Nullable String beanClassName); @Nullable String getBeanClassName(); void setScope(@Nullable String scope); @Nullable String getScope(); void setLazyInit(boolean lazyInit); boolean isLazyInit(); void setDependsOn(@Nullable String... dependsOn); @Nullable String[] getDependsOn(); void setAutowireCandidate(boolean autowireCandidate); boolean isAutowireCandidate(); void setPrimary(boolean primary); boolean isPrimary(); void setFactoryBeanName(@Nullable String factoryBeanName); @Nullable String getFactoryBeanName(); void setFactoryMethodName(@Nullable String factoryMethodName); @Nullable String getFactoryMethodName(); ConstructorArgumentValues getConstructorArgumentValues(); default boolean hasConstructorArgumentValues() { return !getConstructorArgumentValues().isEmpty(); } MutablePropertyValues getPropertyValues(); default boolean hasPropertyValues() { return !getPropertyValues().isEmpty(); } void setInitMethodName(@Nullable String initMethodName); @Nullable String getInitMethodName(); void setDestroyMethodName(@Nullable String destroyMethodName); @Nullable String getDestroyMethodName(); void setRole(int role); int getRole(); void setDescription(@Nullable String description); @Nullable String getDescription(); // Read-only attributes ResolvableType getResolvableType(); boolean isSingleton(); boolean isPrototype(); boolean isAbstract(); @Nullable String getResourceDescription(); @Nullable BeanDefinition getOriginatingBeanDefinition(); }

  可以看出,这些定义与 bean 标签的属性和子元素基本一一对应。

 

2、BeanDefinition 体系

  在 BeanDefinition 体系 中已经提到 BeanDefinition 的继承结构,这里抄过来:

技术图片

 

2.1、BeanDefinition 的父接口

  从继承结构中可以看到, BeanDefinition 继承了 2 个父接口,分别是 AttributeAccessor 和 BeanMetadataElement :

  • org.springframework.core.AttributeAccessor : 定义了向任意对象附加和访问元数据的通用约定接口,例如对属性的获取、设置、删除等。
/**
 * Interface defining a generic contract for attaching and accessing metadata
 * to/from arbitrary objects.
 * 

定义了向任意对象附加和访问元数据的通用约定接口,例如对属性的获取、设置、删除等

*/ 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(); }
  • org.springframework.beans.BeanMetadataElement : 用于获取 bean 配置元数据元素的配置源
/**
 * Interface to be implemented by bean metadata elements
 * that carry a configuration source object.
 * 

用于获取 bean 配置元数据元素的配置源

*/ public interface BeanMetadataElement { /** * Return the configuration source {@code Object} for this metadata element * (may be {@code null}). */ @Nullable default Object getSource() { return null; } }

 

2.2、BeanDefinition 的子类

  BeanDefinition 的抽象子类 AbstractBeanDefinition 进行了一些基本方法的通用实现,这里我们主要关系3个实现类:

  • org.springframework.beans.factory.support.GenericBeanDefinition
  • org.springframework.beans.factory.support.RootBeanDefinition
  • org.springframework.beans.factory.support.ChildBeanDefinition

  这3个实现类都继承了 AbstractBeanDefinition 。在配置文件中可以定义父 和子 ,其中,父 用 RootBeanDefinition 表示,子 用 ChildBeanDefinition 表示,而没有父 的则使用 RootBeanDefinition 进行表示,可以说 RootBeanDefinition 是最常用的实现类,对应一般性的元素标签。而 GenericBeanDefinition 则是自 2.5 版本以后新加入的 bean 文件配置属性定义类,是一站式服务类:

/**
 * GenericBeanDefinition is a one-stop shop for standard bean definition purposes.
 * Like any bean definition, it allows for specifying a class plus optionally
 * constructor argument values and property values. Additionally, deriving from a
 * parent bean definition can be flexibly configured through the "parentName" property.
 * 

用于标准 bean 定义的一站式服务类。与其他任意 bean 定义一样,它允许指定类以及可选 * 的构造器参数和属性值。此外,可以通过 parentName 属性灵活的配置父 bean 定义 * *

In general, use this {

@code GenericBeanDefinition} class for the purpose of * registering user-visible bean definitions (which a post-processor might operate on, * potentially even reconfiguring the parent name). Use {@code RootBeanDefinition} / * {@code ChildBeanDefinition} where parent/child relationships happen to be pre-determined. *

通常,使用这个 GenericBeanDefinition 类来注册用户可见的bean定义(后处理器可能对其进行操作, * 甚至可能重新配置 parentName )。如果父/子关系是预先确定的,请使用 RootBeanDefinition / ChildBeanDefinition。 * *

@author Juergen Hoeller * @since 2.5 * @see #setParentName * @see RootBeanDefinition * @see ChildBeanDefinition */ @SuppressWarnings("serial") public class GenericBeanDefinition extends AbstractBeanDefinition { @Nullable private String parentName; // .... }

 

2.3、抽象子类 AbstractBeanDefinition 的属性

  解析过程中使用的是 AbstractBeanDefinition ,这里我们重点看下对应的属性:

public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccessor
        implements BeanDefinition, Cloneable {

    /// 忽略一堆 static final 属性


    @Nullable
    private volatile Object beanClass;

    /**
     * bean 的作用范围,对应 bean 属性 scope
     */
    @Nullable
    private String scope = SCOPE_DEFAULT;

    /**
     * 是否抽象,对应 bean 属性 abstract
     */
    private boolean abstractFlag = false;

    /**
     * 是否延迟加载,对应 bean 属性 lazy-init
     */
    @Nullable
    private Boolean lazyInit;

    /**
     * 自动诸如模式,对应 bean 属性 autowire
     */
    private int autowireMode = AUTOWIRE_NO;

    /**
     * 依赖检查,Spring3.0之后弃用这个属性
     */
    private int dependencyCheck = DEPENDENCY_CHECK_NONE;

    /**
     * 用来表示一个 bean 的实例化依靠另一个 bean 先实例化,对应 bean 属性 depend-on
     */
    @Nullable
    private String[] dependsOn;

    /**
     * autowire-candidate 属性这只为 true ,这样容器在查找自动装配对象时,将不考虑该 bean ,
     * 即它不会倍考虑作为其他 bean 自动装配的候选者,但是该 bean 本身是可以使用自动装配来
     * 注入其他 bean 的
     */
    private boolean autowireCandidate = true;

    /**
     * 自动装配时当出现多个 bean 候选者时,将作为首选者,对应 bean 属性 primary
     */
    private boolean primary = false;

    /**
     * 用于记录 Qualifier ,对应子元素 qualifier
     */
    private final Map qualifiers = new LinkedHashMap();

    @Nullable
    private Supplier> instanceSupplier;

    /**
     * 允许访问非公开的构造器和方法
     */
    private boolean nonPublicAccessAllowed = true;

    /**
     * 是否以一种宽松的模式解析构造函数,默认 true
     */
    private boolean lenientConstructorResolution = true;

    /**
     * 对应 bean 属性 factory-bean
     */
    @Nullable
    private String factoryBeanName;

    /**
     * 对应 bean 属性 factory-method
     */
    @Nullable
    private String factoryMethodName;

    /**
     * 记录构造函数注入属性,对应 bean 属性 constructor-arg
     */
    @Nullable
    private ConstructorArgumentValues constructorArgumentValues;

    /**
     * 普通属性 property 集合
     */
    @Nullable
    private MutablePropertyValues propertyValues;

    /**
     * 方法重写的持有者,记录 lookup-method 和 replaced-method 元素
     */
    private MethodOverrides methodOverrides = new MethodOverrides();

    /**
     * 初始化方法,对应 bean 属性 init-method
     */
    @Nullable
    private String initMethodName;

    /**
     * 销毁方法,对应 bean 属性 destroy-method
     */
    @Nullable
    private String destroyMethodName;

    /**
     * 是否执行 init-method 方法
     */
    private boolean enforceInitMethod = true;

    /**
     * 是否执行 destroy-method 方法
     */
    private boolean enforceDestroyMethod = true;

    /**
     * 是否是用户定义的而不是应用程序本身定义的,创建 AOP 时为 true ,程序设置
     */
    private boolean synthetic = false;

    /**
     * 定义这个 bean 的角色范围,ROLE_APPLICATION:用户;ROLE_INFRASTRUCTURE:完全内部使用,与用户无关;
     * ROLE_SUPPORT:某些复杂配置的一部分程序设置
     */
    private int role = BeanDefinition.ROLE_APPLICATION;

    /**
     * bean 的描述信息
     */
    @Nullable
    private String description;

    /**
     * bean 定义涉及到的资源
     */
    @Nullable
    private Resource resource;
    
    ///....
}

  可以看到一些比较常用的属性定义了,后面相关元素或者属性的解析都会一一对应上。

 

3、总结

  至此,我们可以看出: BeanDefinition 其实就是 spring 内部对 bean 标签的表示形式。后续将一一进行 bean 标签具体属性和子元素的解析分析。

 

4、参考

  • spring 官方文档 5.2.3.RELEASE:https://docs.spring.io/spring-framework/docs/5.2.3.RELEASE/spring-framework-reference/core.html
  • Spring源码深度解析(第2版),郝佳,P44-P72
  • 相关注释可参考笔者 github 链接:https://github.com/wpbxin/spring-framework

 

Spring5源码分析(013)——IoC篇之解析bean标签:BeanDefinition 和 AbstractBeanDefinition

标签:tor   return   data   完全   rop   clone   官方文档   placed   generic   

原文地址:https://www.cnblogs.com/wpbxin/p/13550949.html


评论


亲,登录后才可以留言!