spring BeanDefinition Bean的注册

参考

BeanDefinition继承关系

如图:



红圈的五个类都值得分析一下。

BeanDefinition

官方解释:
BeanDefinition是Bean的定义,描述了一个Bean实例。它包含了描述一个Bean所需的最少接口方法。一个BeanDefinition会有属性值、构造器参数和其它更多信息(取决于具体实现)。

我的理解:
通过解析xml的<bean>节点,或者解析注解类,会将Bean的定义设置到BeanDefinition。但仅仅是BeanDefinition各种成员变量的设置,还没有实例化对象。
换句话说,对于xml解析法,只是把xml的<bean>文本转换为BeanDefinition对象而已;对于注解法,只是把注解的类转换为BeanDefinition对象而已。

常用的一般是GenericBeanDefinition和AnnotatedGenericBeanDefinition。

AbstractBeanDefinition

属性解析
Spring源码解析——AbstractBeanDefinition属性

BeanDefinitionHolder

public class BeanDefinitionHolder implements BeanMetadataElement {
    private final BeanDefinition beanDefinition;
    private final String beanName;
    @Nullable
    private final String[] aliases;
    // ...
}

在解析出BeanDefinition后,会再度封装出BeanDefinitionHolder。
BeanDefinitionHolder其实就是BeanDefinition加上beanName和一些别名。BeanDefinition本身包含了Bean的定义,但没包含beanName和别名。

RootBeanDefinition

  • Spring容器技术内幕之BeanDefinition类介绍

  • 另见spring源码(11)bean的parent属性详解和获取RootBeanDefinition

  • RootBeanDefinition是最常用地实现类,它对应一般性地< bean > 元素标签。我们知道,在配置文件中可以定义父< bean >和子< bean >,父< bean >用RootBeanDefiniton表示,子< bean >用ChildBeanDefinition表示,而没有父< bean >的< bean >则用RootBeanDefinition表示。AbstractBeanDefintion对二者共同的类信息进行抽象。

  • 从spring2.5起,注册bean的首选是GenericBeanDefinition,GenericBeanDefinition允许动态的定义父bean(通过setParentName方法)。

创建BeanDefinition

创建BeanDefinition主要包括两个步骤:

  • 利用BeanDefinitionReader读取承载配置信息的Resource,通过XML解析器解析配置信息的DOM对象,简单地每个< bean >生成对应地BeanDefinition对象。但是这里生成的BeanDefinition可能是半成品,因为在配置文件中,可能通过占位符变量引用外部属性文件的属性,这些占位符变量在这一步里还没有被解析出来;
  • 利用容器中注册的BeanFatoryPostProcessor对半成品的BeanDefinition进行加工处理,将以占位符表示的配置解析为最终的实际值,这样半成品的BeanDefinition就成为成品的BeanDefinition。

Bean源码解析


  • DefaultBeanDefinitionDocumentReader.parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) 会解析<beans>节点
  • DefaultBeanDefinitionDocumentReader.parseDefaultElement会解析<beans>的非自定义子节点
  • BeanDefinitionParserDelegate.parseBeanDefinitionElement会解析<bean>节点
  • 由SimpleAliasRegistry.aliasMap保存别名关系
  • 由DefaultListableBeanFactory.beanDefinitionMap保存beanName-beanDefinition映射关系。

解析时会调用到BeanDefinitionReaderUtils.registerBeanDefinition:

public static void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
        throws BeanDefinitionStoreException {

    // Register bean definition under primary name.
    String beanName = definitionHolder.getBeanName();
    registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());

    // Register aliases for bean name, if any.
    String[] aliases = definitionHolder.getAliases();
    if (aliases != null) {
        for (String alias : aliases) {
            registry.registerAlias(beanName, alias);
        }
    }
}

在此注册BeanDefinition和别名。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容