介绍

在SpringIOC流程分析过程中,对于Bean的控制反转创建过程一定离不开BeanDefinition.虽然它是接口,基于它有AbstractBeanDefinition,RootBeanDefinition,GenericBeanDefinition等各种实现.创建Bean的过程也会将不同的BeanDefinition转成RootBeanDefinition来进行使用.
它经过Spring解析对应类或配置保存了该Bean的各种信息,例如该Bean的类型、是否是抽象类、作用域、该Bean的初始化,销毁方法、需要注入那些Bean等.
可以理解为存放Bean创建所需的材料列表.然后Spring根据创建说明来进行Bean的创建操作
创建说明包含材料获取以及生成.BeanDefinitionRegistry负责BeanDefinition注册即材料获取环节,BeanFactory负责Bean的创建环节,管控Bean的部分生命周期.最后交由Spring容器调度

例外

通过beanFactory.registerSingleton方法手动加入Bean是不会用到BeanDefinition的,这里是将现有Bean加入BeanFactory中.
例如: bf.registerSingleton(WebApplicationContext.SERVLET_CONTEXT_BEAN_NAME, servletContext);

BeanDefinition接口

/**
 * 该接口主要定义一些基础Bean元数据信息属性值以及基础属性获取方法
 */
 public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {

    // 定义单例/多例的常量值
    String SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON;
    String SCOPE_PROTOTYPE = ConfigurableBeanFactory.SCOPE_PROTOTYPE;

    // 定义Bean的作用角色.
    // 0表示应用级.1表示配置拓展支撑级.2表示内部构造级。0,1为自定义级别
    int ROLE_APPLICATION = 0;
    int ROLE_SUPPORT = 1;
    int ROLE_INFRASTRUCTURE = 2;

    // 下面是可修改的定义属性

    // 指定父类
    void setParentName(@Nullable String parentName);
    @Nullable
    String getParentName();

    // 当前类
    void setBeanClassName(@Nullable String beanClassName);
    @Nullable
    String getBeanClassName();

    // 指定作用域.SCOPE_SINGLETON或者SCOPE_PROTOTYPE两种
    void setScope(@Nullable String scope);
    @Nullable
    String getScope();

    // 指定是否懒加载
    void setLazyInit(boolean lazyInit);
    boolean isLazyInit();

    // 指定依赖对象列表
    void setDependsOn(@Nullable String... dependsOn);
    @Nullable
    String[] getDependsOn();

    // 是否支持自动注入.支持的才可以被注入到其他地方.只支持@Autorire方式判断
    void setAutowireCandidate(boolean autowireCandidate);
    boolean isAutowireCandidate();

    // 当多Bean类型重复是否是注入Bean的首选
    void setPrimary(boolean primary);
    boolean isPrimary();

    // 设置该Bean的工厂Bean(专门创建该Bean的工厂).
    void setFactoryBeanName(@Nullable String factoryBeanName);
    @Nullable
    String getFactoryBeanName();

    // 设置工厂方法.
    void setFactoryMethodName(@Nullable String factoryMethodName);
    @Nullable
    String getFactoryMethodName();

    ConstructorArgumentValues getConstructorArgumentValues();
    default boolean hasConstructorArgumentValues() {
        return !getConstructorArgumentValues().isEmpty();
    }

    // 该Bean的属性集合
    MutablePropertyValues getPropertyValues();
    default boolean hasPropertyValues() {
        return !getPropertyValues().isEmpty();
    }

    // 初始化执行方法. @PostConstruct注解标注的/配置文件指定的.
    void setInitMethodName(@Nullable String initMethodName);
    @Nullable
    String getInitMethodName();

    // 销毁执行方法 @PreDestroy注解标注的/配置文件指定的.
    // 也可以@Bean(initMethod = "init",destroyMethod = "destory")指定
    void setDestroyMethodName(@Nullable String destroyMethodName);
    @Nullable
    String getDestroyMethodName();

    // 设置该Bean角色
    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();
    // 返回最原始BeanDefinition.当该Bean有被其他postProcessor处理过(代理修饰).则该方法可以返回最原先的BeanDefinition
    @Nullable
    BeanDefinition getOriginatingBeanDefinition();

}

子接口AnnotatedBeanDefinition定义访问目标类注解信息接口

// 该类意思是无需加载目标类即可获取目标类的信息
public interface AnnotatedBeanDefinition extends BeanDefinition {

    // 获取类上的注解信息
    AnnotationMetadata getMetadata();

    // 如果该Bean定义了工厂方法,则返回工厂方法元数据信息
    // 名字、返回类型、是否抽象、是否是静态的、是否不可继承、是否可重写
    @Nullable
    MethodMetadata getFactoryMethodMetadata();

}

AbstractBeanDefinition定义了Bean创建默认配置

public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccessor
        implements BeanDefinition, Cloneable {

    //默认的SCOPE,默认是单例
    public static final String SCOPE_DEFAULT = "";

    // 自动装配常量类型定义: 是否自动装配、根据名称/类型/构造器装配 
    public static final int AUTOWIRE_NO = AutowireCapableBeanFactory.AUTOWIRE_NO;
    public static final int AUTOWIRE_BY_NAME = AutowireCapableBeanFactory.AUTOWIRE_BY_NAME;
    public static final int AUTOWIRE_BY_TYPE = AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE;
    public static final int AUTOWIRE_CONSTRUCTOR = AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR;
    @Deprecated
    public static final int AUTOWIRE_AUTODETECT = AutowireCapableBeanFactory.AUTOWIRE_AUTODETECT;

    //检查依赖是否合法,在本类中,默认不进行依赖检查
    public static final int DEPENDENCY_CHECK_NONE = 0; // 不进行检查
    public static final int DEPENDENCY_CHECK_OBJECTS = 1; //如果依赖类型为对象引用,则需要检查
    public static final int DEPENDENCY_CHECK_SIMPLE = 2; //对简单属性的依赖进行检查
    public static final int DEPENDENCY_CHECK_ALL = 3; //对所有属性的依赖进行检查

    //若Bean未指定销毁方法,容器应该尝试推断Bean的销毁方法的名字,目前来说,推断的销毁方法的名字一般为close或是shutdown
    //(即未指定Bean的销毁方法,但是内部定义了名为close或是shutdown的方法,则容器推断其为销毁方法)
    public static final String INFER_METHOD = "(inferred)";


    //定义一些SpringIOC的默认属性信息

    //Bean的class对象或是类的全限定名
    @Nullable
    private volatile Object beanClass;

    //默认的scope是单例
    @Nullable
    private String scope = SCOPE_DEFAULT;
    //默认不为抽象类
    private boolean abstractFlag = false;
    //默认不懒加载
    private boolean lazyInit = false;
    //默认是没有依赖注入的模式
    private int autowireMode = AUTOWIRE_NO;
    //默认不进行依赖检查
    private int dependencyCheck = DEPENDENCY_CHECK_NONE;
    // @@DependsOn 默认没有依赖
    @Nullable
    private String[] dependsOn;
    // 是否支持自动装配
    // false时,容器在查找自动装配对象时,将不考虑该bean
    private boolean autowireCandidate = true;
    // 默认不是首选的
    private boolean primary = false;

    //存储该Bean依赖中使用@Qualifier标注的自动装配信息,多指定依赖的Bean名称.防止多个同类型Bean造成的NoUniqueBeanDefinitionException异常
    private final Map<String, AutowireCandidateQualifier> qualifiers = new LinkedHashMap<>(0);
    //我理解为通过这个函数的逻辑初始化Bean,而不是构造函数或是工厂方法(相当于自己去实例化,而不是交给Bean工厂)
    @Nullable
    private Supplier<?> instanceSupplier;
    //是否允许访问非public方法和属性,应用于构造函数、工厂方法、init、destroy方法的解析 默认是true,表示啥都可以访问
    private boolean nonPublicAccessAllowed = true;
    // 是否以一种宽松的模式解析构造函数,默认为true(宽松和严格体现在类型匹配上)
    private boolean lenientConstructorResolution = true;
    //工厂类名(注意是String类型,不是Class类型) 对应bean属性factory-method
    @Nullable
    private String factoryBeanName;
    //工厂方法名(注意是String类型,不是Method类型)
    @Nullable
    private String factoryMethodName;
    //记录构造函数注入属性,对应bean属性constructor-arg
    @Nullable
    private ConstructorArgumentValues constructorArgumentValues;

    //Bean属性的名称以及对应的值,这里不会存放构造函数相关的参数值,只会存放通过setter注入的依赖
    @Nullable
    private MutablePropertyValues propertyValues;
    //方法重写的持有者,记录lookup-method、replaced-method元素  @Lookup等
    @Nullable
    private MethodOverrides methodOverrides;

    //init函数的名字
    @Nullable
    private String initMethodName;
    //destory函数的名字
    @Nullable
    private String destroyMethodName;
    //是否执行init-method,程序设置
    private boolean enforceInitMethod = true;
    private boolean enforceDestroyMethod = true;

    //是否是合成类(是不是应用自定义的,例如生成AOP代理时,会用到某些辅助类,这些辅助类不是应用自定义的,这个就是合成类)
    //创建AOP时候为true
    private boolean synthetic = false;

    //Bean的角色,为用户自定义Bean
    private int role = BeanDefinition.ROLE_APPLICATION;

    // Bean的描述信息
    @Nullable
    private String description;
    //the resource that this bean definition came from
    // 类的源信息(加载一个类可能是一个文件/网络地址)
    @Nullable
    private Resource resource;

    // 其实就是给reource赋值了,使用了BeanDefinitionResource
    public void setOriginatingBeanDefinition(BeanDefinition originatingBd) {
        this.resource = new BeanDefinitionResource(originatingBd);
    }
    // 上面有赋值,所以get的时候就是返回上面set进来的值
    public BeanDefinition getOriginatingBeanDefinition() {
        return (this.resource instanceof BeanDefinitionResource ?
                ((BeanDefinitionResource) this.resource).getBeanDefinition() : null);
    }

    //克隆Bean的定义信息
    @Override
    public Object clone() {
        return cloneBeanDefinition();
    }
    public abstract AbstractBeanDefinition cloneBeanDefinition();
}

RootBeanDefinition

生成Bean时会将不同的BeanDefinition合并成RootBeanDefinition.当某个类有父类会将父类的BeanDefinition合并进该类的BeanDefinition中.在AbstractBeanFactory.doGetBean方法中,也是Context.refresh的第十一步执行

public class RootBeanDefinition extends AbstractBeanDefinition {

    //BeanDefinitionHolder存储有Bean的名称、别名、BeanDefinition
    @Nullable
    private BeanDefinitionHolder decoratedDefinition;
    // AnnotatedElement 是java反射包的接口,通过它可以查看Bean的注解信息
    @Nullable
    private AnnotatedElement qualifiedElement;
    //允许缓存
    boolean allowCaching = true;
    //从字面上理解:工厂方法是否唯一
    boolean isFactoryMethodUnique = false;
    //封装了java.lang.reflect.Type,提供了泛型相关的操作,具体请查看:
    // ResolvableType 可以专题去了解一下子,虽然比较简单 但常见
    @Nullable
    volatile ResolvableType targetType;
    //缓存class,表明RootBeanDefinition存储哪个类的信息
    @Nullable
    volatile Class<?> resolvedTargetType;
    //缓存工厂方法的返回类型
    @Nullable
    volatile ResolvableType factoryMethodReturnType;

    /** Common lock for the four constructor fields below */
    final Object constructorArgumentLock = new Object();

    //缓存已经解析的构造函数或是工厂方法,Executable是Method、Constructor类型的父类
    @Nullable
    Executable resolvedConstructorOrFactoryMethod;
    //表明构造函数参数是否解析完毕
    boolean constructorArgumentsResolved = false;
    //缓存完全解析的构造函数参数
    @Nullable
    Object[] resolvedConstructorArguments;
    //缓存待解析的构造函数参数,即还没有找到对应的实例,可以理解为还没有注入依赖的形参
    @Nullable
    Object[] preparedConstructorArguments;

    /** Common lock for the two post-processing fields below */
    final Object postProcessingLock = new Object();

    //表明是否被MergedBeanDefinitionPostProcessor处理过
    boolean postProcessed = false;
    //在生成代理的时候会使用,表明是否已经生成代理
    @Nullable
    volatile Boolean beforeInstantiationResolved;

    //实际缓存的类型是Constructor、Field、Method类型
    @Nullable
    private Set<Member> externallyManagedConfigMembers;
    //InitializingBean中的init回调函数名——afterPropertiesSet会在这里记录,以便进行生命周期回调
    @Nullable
    private Set<String> externallyManagedInitMethods;
    //DisposableBean的destroy回调函数名——destroy会在这里记录,以便进行生命周期回调
    @Nullable
    private Set<String> externallyManagedDestroyMethods;
}

AnnotatedGenericBeanDefinition

AnnotatedGenericBeanDefinition只能用于已经被注册或被扫描到的类

public static void main(String[] args) {
    AnnotatedBeanDefinition beanDefinition = new AnnotatedGenericBeanDefinition(RootConfig.class);
    // 获取注解方式便捷
    Set<String> annotationTypes = beanDefinition.getMetadata().getAnnotationTypes();
    System.out.println(annotationTypes); //[org.springframework.context.annotation.ComponentScan, org.springframework.context.annotation.Configuration]
    System.out.println(beanDefinition.isSingleton()); //true
    System.out.println(beanDefinition.getBeanClassName()); //com.config.RootConfig
}

ConfigurationClassBeanDefinition

是ConfigurationClassBeanDefinitionReader的一个私有的静态内部类:这个类负责将@Bean注解的方法转换为对应的ConfigurationClassBeanDefinition类(非常的重要),直接继承自RootBeanDefinition

最后

Spring初始化时,会用GenericBeanDefinition或是ConfigurationClassBeanDefinition(用@Bean注解注释的类)存储用户自定义的Bean,在初始化Bean时,又会将其转换为RootBeanDefinition

参考

Spring IoC容器中核心定义之------BeanDefinition深入分析