Spring 源码阅读笔记 - 浅析 bean 从读取到注册入 beanFactory 的流程

  在 Spring 框架中管理 Bean 的注册过程,可以通过一个形象的比喻来理解:将 Bean 视作一件件“商品”。它可能由不同的创作者(作者)设计,拥有自己的产地(Class),可以是独一无二的艺术品(Singleton),也可以是工厂流水线上批量生产的复制品(Prototype)。   要让一个 Bean 被 Spring 容器识别,首先需要“登记”它的信息。以注解配置为例,我们可以通过 @Bean、@Service 等注解将一个普通的 POJO 声明为 Bean;或者通过 @ComponentScan 批量扫描某个包路径下的所有类,自动将其注册为 Bean。   随后,AnnotationConfigApplicationContext 会接手这些 Bean,并通过内置的 BeanDefinitionReader 解析它们的元数据,包括: 来源地(Class 类型) 作用域(Scope,如单例或原型)   解析后的信息会被封装成一个 GenericBeanDefinition 对象。接下来,需要将 Bean 的名称与其定义建立映射,并存入一个“容器”中——这就是 BeanFactory 的核心作用。具体来说,是由 DefaultListableBeanFactory 来实现的。其内部维护了一个默认容量为 256 的 ConcurrentHashMap,Bean 的注册实质上就是执行一次 map.put(beanName, beanDefinition)。同时,它也提供了 getBean() 方法,用于根据名称获取对应的 Bean 实例。   虽然 Bean 的实际注册逻辑是在 DefaultListableBeanFactory 中完成的,但从调用链路来看,我们通常沿着这样的路径: text AnnotationConfigApplicationContext → reader.doRegisterBean() → BeanDefinitionRegistryUtils.registerBeanDefinition() → registry.registerBeanDefinition()   表面上看,这个过程似乎并未直接涉及 BeanFactory。这是因为 Spring 在源码层做了高度的抽象:AnnotationConfigApplicationContext 和 DefaultListableBeanFactory 有一个共同的父级接口 BeanDefinitionRegistry,其中定义了 Bean 注册的方法。而 DefaultListableBeanFactory 实现了这个接口。   实际上,在 GenericApplicationContext 初始化时,会内部创建一个 DefaultListableBeanFactory 实例。AnnotationConfigApplicationContext 继承自 GenericApplicationContext,并实现了 BeanDefinitionRegistry 接口,从而在调用注册方法时,会将自身作为 registry 参数传入,最终委托给内部的 DefaultListableBeanFactory 完成真正的注册操作。   简而言之,Spring 通过多层接口与实现类的协作,将功能职责清晰分离,虽然在调用链路上显得有些“绕”,但这样的设计极大地提升了框架的灵活性与可扩展性。

0个评论
点击登录,快来和大家讨论吧~
表情
图片
暂无评论
F1ower
下载 APP