该系列文章是本人在学习 Spring 的过程当中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合个人源码注释 Spring 源码分析 GitHub 地址 进行阅读html
Spring 版本:5.1.14.RELEASEjava
开始阅读这一系列文章以前,建议先查看《深刻了解 Spring IoC(面试题)》这一篇文章git
该系列其余文章请查看:《死磕 Spring 之 IoC 篇 - 文章导读》github
咱们在 Spring 中一般以这两种方式定义一个 Bean:面向资源(XML、Properties)、面向注解。现在 Spring Boot 被普遍应用,经过注解定义一个 Bean 的方式变得更为广泛,由于在实际的开发过程当中注解的方式相比于 XML 文件更加轻便,能够有效地提升工做效率。你是否这了解这两种方式在 Spring 内是如何进行处理的,将咱们的配置信息转换成 Spring Bean,并管理着这些它们的生命周期面试
在 Spring Bean 的生命周期 能够看到,BeanDefinition 能够说是 Bean 的“前身”,首先进入 Bean 的元信息的配置、解析和注册阶段,而后才开始 Bean 的实例化和初始化等工做。接下来,咱们就一块儿来看看 Bean 的“前身”是什么spring
BeanDefinition 是 Spring Framework 中定义 Bean 的配置元信息接口,主要包含一下信息:框架
org.springframework.beans.factory.config.BeanDefinition
接口的类图以下所示:ide
总览:源码分析
org.springframework.core.AttributeAccessor
接口,用于获取元数据,在实现类中经过 LinkedHashMap 集合保存元数据,例如经过 XML 的 <meta />
标签订义的一些元信息会保存在其中学习
org.springframework.beans.BeanMetadataElement
接口,用于获取定义 Bean 的源对象,在实现类中经过 Object 对象保存,所谓的源对象就是定义这个 Bean 的资源(XML 标签对象或者 .class 文件资源对象)
org.springframework.beans.factory.config.BeanDefinition
接口,定义一个 Bean 的元信息
org.springframework.beans.factory.support.AbstractBeanDefinition
抽象类,实现 BeanDefinition 接口,包含了一个 Bean 几乎全部的元信息
org.springframework.beans.factory.support.GenericBeanDefinition
,继承 AbstractBeanDefinition 抽象类,多了一个 parentName
,表示有继承关系,是一个标准 Bean 元信息对象,经过 XML 定义的 Bean 会解析成该对象
org.springframework.beans.factory.annotation.AnnotatedBeanDefinition
接口,继承 BeanDefinition 接口,定义注解类的元信息,例如经过 @Component
注解定义的 Bean,那么注解类的元信息会包含编译后的 .class 文件的全部信息
org.springframework.context.annotation.ScannedGenericBeanDefinition
,继承 GenericBeanDefinition,实现 AnnotatedBeanDefinition 接口,多了一个 AnnotationMetadata 注解类元信息对象,例如经过 @Component
注解定义的 Bean 会解析成该对象
org.springframework.beans.factory.annotation.AnnotatedGenericBeanDefinition
,继承 GenericBeanDefinition,实现 AnnotatedBeanDefinition 接口,和 ScannedGenericBeanDefinition 相似,经过 @Import
导入的 Configuration Class
会解析成该对象
org.springframework.beans.factory.support.RootBeanDefinition
,继承 AbstractBeanDefinition 抽象类,表示合并后的 BeanDefinition 对象。在 Spring BeanFactory 初始化 Bean 的前阶段,会根据 BeanDefinition 生成一个 RootBeanDefinition(具备层次性则会进行合并),用于后续实例化和初始化
org.springframework.context.annotation.ConfigurationClassBeanDefinition$ConfigurationClassBeanDefinition
私有静态类,继承 RootBeanDefinition,实现了 AnnotatedBeanDefinition 接口,和 AnnotatedGenericBeanDefinition 相似,没有继承关系,经过 @Bean
定义的方法会解析成该对象
org.springframework.beans.factory.config.BeanDefinitionHolder
,包含 BeanDefinition、Bean 的名称以及别名(支持多个)总结一下,BeanDefinition 接口的实现类主要根据 Bean 的定义方式进行区分,以下:
XML 定义 Bean >>>>> GenericBeanDefinition
@Component 以及派生注解定义 Bean >>>>> ScannedGenericBeanDefinition
借助于 @Import 导入 Bean >>>>> AnnotatedGenericBeanDefinition
@Bean 定义的方法 >>>>> ConfigurationClassBeanDefinition
在 Spring BeanFactory 初始化 Bean 的前阶段,会根据 BeanDefinition 生成一个合并后的 RootBeanDefinition 对象
org.springframework.beans.factory.config.BeanDefinition
接口,继承 AttributeAccessor 和 BeanMetadataElement 两个接口,定义一个 Bean 的元信息
BeanDefinition 内部就定义了获取一些基础元信息的方法,可跳转 BeanDefinition.java 查看
org.springframework.beans.factory.support.AbstractBeanDefinition
抽象类,实现 BeanDefinition 接口,继承 BeanMetadataAttributeAccessor 类(AttributeAccessor 和 BeanMetadataElement 的实现类),包含了一个 Bean 几乎全部的元信息,可跳转 AbstractBeanDefinition.java 查看,下面列举最多见的属性:
public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccessor implements BeanDefinition, Cloneable { @Nullable private volatile Object beanClass; private boolean abstractFlag = false; private boolean lazyInit = false; @Nullable private String[] dependsOn; private boolean primary = false; private boolean nonPublicAccessAllowed = true; @Nullable private String factoryBeanName; @Nullable private String factoryMethodName; @Nullable private ConstructorArgumentValues constructorArgumentValues; @Nullable private MutablePropertyValues propertyValues; @Nullable private String initMethodName; @Nullable private String destroyMethodName; private boolean enforceInitMethod = true; private boolean enforceDestroyMethod = true; private boolean synthetic = false; private int role = BeanDefinition.ROLE_APPLICATION; @Nullable private String description; @Nullable private Resource resource; // ... 省略大量代码 }
org.springframework.beans.factory.support.GenericBeanDefinition
,继承 AbstractBeanDefinition 抽象类,多了一个 parentName
,表示有继承关系,是一个标准 Bean 元信息对象,经过 XML 定义的 Bean 会解析成该对象,代码以下:
public class GenericBeanDefinition extends AbstractBeanDefinition { @Nullable private String parentName; public GenericBeanDefinition() { super(); } public GenericBeanDefinition(BeanDefinition original) { super(original); } // ... 省略相关方法 }
org.springframework.beans.factory.annotation.AnnotatedBeanDefinition
接口,继承 BeanDefinition 接口,定义注解类的元信息,代码以下:
public interface AnnotatedBeanDefinition extends BeanDefinition { /** * Obtain the annotation metadata (as well as basic class metadata) * for this bean definition's bean class. * @return the annotation metadata object (never {@code null}) */ AnnotationMetadata getMetadata(); /** * Obtain metadata for this bean definition's factory method, if any. * @return the factory method metadata, or {@code null} if none * @since 4.1.1 */ @Nullable MethodMetadata getFactoryMethodMetadata(); }
AnnotationMetadata 能够获取到定义 Bean 的全部信息,在 Spring 底层会经过 ASM(一个操做 Java 字节码与分析的框架)实现的
MethodMetadata 能够获取到工厂方法的元信息,目前我没发现哪里使用到
例如经过 @Component
注解定义的 Bean,那么 AnnotationMetadata 能够获取到这个 Class 对象的全部信息
org.springframework.context.annotation.ScannedGenericBeanDefinition
,继承 GenericBeanDefinition,实现 AnnotatedBeanDefinition 接口,多了一个 AnnotationMetadata 注解类元信息对象,例如经过 @Component
注解定义的 Bean 会解析成该对象,代码以下:
public class ScannedGenericBeanDefinition extends GenericBeanDefinition implements AnnotatedBeanDefinition { private final AnnotationMetadata metadata; public ScannedGenericBeanDefinition(MetadataReader metadataReader) { Assert.notNull(metadataReader, "MetadataReader must not be null"); this.metadata = metadataReader.getAnnotationMetadata(); setBeanClassName(this.metadata.getClassName()); } @Override public final AnnotationMetadata getMetadata() { return this.metadata; } @Override @Nullable public MethodMetadata getFactoryMethodMetadata() { return null; } }
org.springframework.beans.factory.annotation.AnnotatedGenericBeanDefinition
,继承 GenericBeanDefinition,实现 AnnotatedBeanDefinition 接口,和 ScannedGenericBeanDefinition 相似,代码以下:
public class AnnotatedGenericBeanDefinition extends GenericBeanDefinition implements AnnotatedBeanDefinition { private final AnnotationMetadata metadata; @Nullable private MethodMetadata factoryMethodMetadata; public AnnotatedGenericBeanDefinition(Class<?> beanClass) { setBeanClass(beanClass); this.metadata = new StandardAnnotationMetadata(beanClass, true); } public AnnotatedGenericBeanDefinition(AnnotationMetadata metadata) { Assert.notNull(metadata, "AnnotationMetadata must not be null"); if (metadata instanceof StandardAnnotationMetadata) { setBeanClass(((StandardAnnotationMetadata) metadata).getIntrospectedClass()); } else { setBeanClassName(metadata.getClassName()); } this.metadata = metadata; } public AnnotatedGenericBeanDefinition(AnnotationMetadata metadata, MethodMetadata factoryMethodMetadata) { this(metadata); Assert.notNull(factoryMethodMetadata, "MethodMetadata must not be null"); setFactoryMethodName(factoryMethodMetadata.getMethodName()); this.factoryMethodMetadata = factoryMethodMetadata; } @Override public final AnnotationMetadata getMetadata() { return this.metadata; } @Override @Nullable public final MethodMetadata getFactoryMethodMetadata() { return this.factoryMethodMetadata; } }
经过 @Import
导入的 Configuration Class
会解析成该对象,不过 factoryMethodMetadata
仍是为 null
org.springframework.beans.factory.support.RootBeanDefinition
,继承 AbstractBeanDefinition 抽象类,表示合并后的 BeanDefinition 对象
在 Spring BeanFactory 初始化 Bean 的前阶段,会根据 BeanDefinition 生成一个 RootBeanDefinition(具备层次性则会进行合并),用于后续实例化和初始化
可跳转 RootBeanDefinition.java 查看
org.springframework.beans.factory.config.BeanDefinitionHolder
,包含 BeanDefinition、Bean 的名称以及别名(支持多个),代码以下:
public class BeanDefinitionHolder implements BeanMetadataElement { private final BeanDefinition beanDefinition; private final String beanName; @Nullable private final String[] aliases; public BeanDefinitionHolder(BeanDefinition beanDefinition, String beanName) { this(beanDefinition, beanName, null); } public BeanDefinitionHolder(BeanDefinition beanDefinition, String beanName, @Nullable String[] aliases) { Assert.notNull(beanDefinition, "BeanDefinition must not be null"); Assert.notNull(beanName, "Bean name must not be null"); this.beanDefinition = beanDefinition; this.beanName = beanName; this.aliases = aliases; } }
在解析出来 BeanDefinition 后都会转换成 BeanDefinitionHolder 对象,而后进行注册
Spring Bean 的“前身”为 BeanDefinition 对象,里面包含了 Bean 的元信息,后续在 Bean 的生命周期中会根据该对象进行实例化和初始化等工做
BeanDefinition 接口的实现类主要根据 Bean 的定义方式进行区分,以下:
XML 定义 Bean:GenericBeanDefinition
@Component 以及派生注解定义 Bean:ScannedGenericBeanDefinition
借助于 @Import 导入 Bean:AnnotatedGenericBeanDefinition
@Bean 定义的方法:ConfigurationClassBeanDefinition 私有静态类
上面的 1
、2
、3
三种 BeanDefinition 实现类具备层次性,在 Spring BeanFactory 初始化 Bean 的前阶段,会根据 BeanDefinition 生成一个合并后的 RootBeanDefinition 对象