引言
本系列将详细讲解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的名称*/@NullableString getParentName();/*** 指定此bean定义的bean类名(对应xml中bean元素的class属性)*/void setBeanClassName(@Nullable String beanClassName);/*** 返回此bean定义的当前bean类名* 注意,如果子定义重写/继承其父类的类名,则这不一定是运行时使用的实际类名。此外,这可能只是调用工厂方法的类,或者在调用方法的工厂bean引用的情况下,它甚至可能是空的。因此,不要认为这是运行时的最终bean类型,而只将其用于单个bean定义级别的解析目的。*/@NullableString getBeanClassName();/*** 设置此bean的生命周期,如:singleton、prototype(对应xml中bean元素的scope属性)*/void setScope(@Nullable String scope);/*** 返回此bean的生命周期,如:singleton、prototype*/@NullableString 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名称*/@NullableString[] 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属性)*/@NullableString getFactoryBeanName();/*** 指定工厂方法(如果有)。此方法将使用构造函数参数调用,如果未指定任何参数,则不使用任何参数调用。该方法将在指定的工厂bean(如果有的话)上调用,或者作为本地bean类上的静态方法调用。* factoryMethodName:工厂方法名称*/void setFactoryMethodName(@Nullable String factoryMethodName);/*** 返回工厂方法名称(对应xml中bean的factory-method属性)*/@NullableString 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初始化方法名称*/@NullableString getInitMethodName();/*** 设置bean销毁方法的名称*/void setDestroyMethodName(@Nullable String destroyMethodName);/*** bean销毁的方法名称*/@NullableString getDestroyMethodName();/*** 设置bean的role信息*/void setRole(int role);/*** bean定义的role信息*/int getRole();/*** 设置bean描述信息*/void setDescription(@Nullable String description);/*** bean描述信息*/@NullableString getDescription();/*** bean类型解析器*/ResolvableType getResolvableType();/*** 是否是单例的bean*/boolean isSingleton();/*** 是否是多列的bean*/boolean isPrototype();/*** 对应xml中bean元素的abstract属性,用来指定是否是抽象的*/boolean isAbstract();/*** 返回此bean定义来自的资源的描述(以便在出现错误时显示上下文)*/@NullableString getResourceDescription();@NullableBeanDefinition getOriginatingBeanDefinition();}
BeanDefinition接口上面还继承了2个接口:
- AttributeAccessor
- BeanMetadataElement
AttributeAccessor接口:属性访问接口
public interface AttributeAccessor {/*** 设置属性->值*/void setAttribute(String name, @Nullable Object value);/*** 获取某个属性对应的值*/@NullableObject getAttribute(String name);/*** 移除某个属性*/@NullableObject removeAttribute(String name);/*** 是否包含某个属性*/boolean hasAttribute(String name);/*** 返回所有的属性名称*/String[] attributeNames();}
这个接口相当于key->value数据结构的一种操作,BeanDefinition继承这个,内部实际上是使用了LinkedHashMap来实现这个接口中的所有方法,通常我们通过这些方法来保存BeanDefinition定义过程中产生的一些附加信息。
BeanMetadataElement接口
public interface BeanMetadataElement {@Nullabledefault 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类型的对象