专栏首页星月小站spring框架通过xml以及注解方式注册BeanDefinition的流程全链路分析

spring框架通过xml以及注解方式注册BeanDefinition的流程全链路分析

文章目录

系列文章主页

Spring框架源码脉络分析系列文章

在上一章节中,主要介绍了SpringIoC、依赖注入和Spring中的Bean与BeanDefinition。可能部分读者还是比较迷茫,BeanDefinition到底是干什么用的,在本章节中,将通过利用Spring实例化Java对象的过程,先带领读者过一遍Spring框架注册BeanDefinition的运行流程,然后再深入其中,详细分析每一个步骤。

Spring注册BeanDefinition流程全链路简述

在Spring容器的实例化过程中,其核心流程其实非常的简单,逻辑也很清晰,主要是三个步骤:

  1. 解析配置
  2. 定位与注册对象
  3. 注入对象

其中,第三步注入对象将在IoC的最后一个章节进行分析,在本章节中主要分析实例化的前两个过程,因为这两个过程和BeanDefinition息息相关。

而在Spring中,前两个过程都整合在了一起,整个过程其实只是一个方法,位于AbstractApplicationContext类下的refresh()方法中的obtainFreshBeanFactory()方法中。refresh()方法又称为容器的刷新与初始化,在容器的刷新与初始化阶段中,一上来就对BeanDefinition进行了解析配置、定位与注册的过程。

在解析配置、定位与注册BeanDefinition的流程中,容器主要做的事情可以抽象出主要的三个阶段如下:

Xml配置方式的资源定位、加载、解析、注册全链路分析

首先,在Spring源码中新建一个module,命名springdemo,然后仿照平时我们写业务的逻辑,创建一个Service层接口与实现类,然后写一个xml配置文件对该Service层接口进行配置,并在Entrance类中进行Xml配置实例化。

这里由于是xml配置形式,所以使用的容器实现类为FileSystemXmlApplicationContext,不熟悉容器类的请点击:容器类的具体介绍章节,这里主要让读者快速全局速览整个流程。

DefaultListableBeanFactory这个类中的registerBeanDefinition(String beanName, BeanDefinition beanDefinition) 方法打一个断点,这个方法是将BeanDefinition及其beanName注册进容器中。然后以Debug方式执行上述代码,不出意外代码会停在断点处。然后我们查看系统调用栈:

此时,当我们利用ApplicationContext applicationContext = new FileSystemXmlApplicationContext(xmlPath);这个经典代码中注册BeanDefinition流程就清晰展示在了眼前。

在上面的系统调用栈中,其实refresh之后所有的方法执行,都还在refresh中,而且仅仅执行了前两行代码,只到obtainFreshBeanFactory()方法,当执行完obtainFreshBeanFactory()方法后,BeanDefinition就已经被注册进容器中了,所以refresh方法是IoC容器的核心部分,是容器加载的核心源码,在本章节中不深入进去分析,在本章节主要快速带领读者明白IoC容器流程脉络,主要在干什么,refresh方法具体分析可以看下一章节:容器的初始化与刷新逻辑

那么obtainFreshBeanFactory()到底在干什么呢?其实前文已经说得很明白了,这一阶段的核心是读取、解析与注册对象。整个逻辑流程如下图所示:

整个过程跳转、经历的接口与类体系讲解章节如下列出,整个流程所经历的大概类与方法流程图也在下方列出,建议对照阅读:

或者点击此链接看高清大图

  • Spring框架通过Xml文件方式加载注册BeanDefinition的思维导图(点击打开看大图)

或者点击此链接看高清大图

下图把系统调用栈的主要流程进行了注释与分析。

注解方式的资源定位、加载、解析、注册全链路分析

由于注解配置方式和xml文件配置方式所用到的容器不同,首先将启动main函数切换成注解形式,并在业务层加上相关@Controller@Service注解

和xml文件配置方式一样,注解方式的BeanDefinition的注册最后依然会来到DefaultListableBeanFactory 这个类中的registerBeanDefinition(String beanName, BeanDefinition beanDefinition)方法,这是因为不管是xml所用到的容器还是注解所用到的容器,其实都继承自一个重要的高级容器抽象类——AbstractRefreshableApplicationContext,在这个类内部实例化了一个DefaultListableBeanFactory容器作为内部容器,将对BeanDefinition的操作委托给了这个内部容器,而其中注册的流程,就在registerBeanDefinition这个方法中执行,所以xml和注解配置最后的BeanDefinition注册步骤都会来到这里。

以Debug模式执行这段代码,会来到断点处,然后我们观察系统调用栈:

会发现,注解容器启动到注册的全链路流程会比xml方式的调用栈浅一些

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Spring框架源码脉络分析(一):IoC与容器、Bean和BeanDefinition

    IoC:即控制反转机制。在Spring中的实现表现为IoC容器,属于Spring Core模块最核心的部分。

    星如月勿忘初心
  • Spring框架源码分析(IoC):BeanFactory和ApplicationContext容器家族

    组件扫描:自动发现应用容器中需要创建的Bean。 自动装配:自动满足Bean之间的依赖。

    星如月勿忘初心
  • Spring-Data-Redis 2.X以上版本使用心得和一些坑

    最近在修改之前旧项目的时候,将spring-data-redis的版本升级到了2.X以上,查看了官方的文档之后,发现新版本有一些新特性和新的使用方法,这里记录整...

    星如月勿忘初心
  • Python 面向对象静态方法、类方法、属性方法知识点小结

    本文实例讲述了Python 面向对象静态方法、类方法、属性方法知识点。分享给大家供大家参考,具体如下:

    砸漏
  • python 大文件切割成小文件(常用)

    def mkSubFile(lines, head, srcName, sub): [des_filename, extname] = os.path.spl...

    用户5760343
  • 用Python实现大文本文件切割

    在实际工作中,有些场景下,因为产品既有功能限制,不支持特大文件的直接处理,需要把大文件进行切割处理。

    py3study
  • 10.31 VR扫描:苹果发布更新MacBookAir及Mac mini,推出最新款iPad Pro

    苹果以“There's more in the making”为主题,对其2个许久未更新的产品线MacBook Air与Mac mini进行了更新,还发布了“世...

    VRPinea
  • 如何用pycococreator将自己的数据集转换为COCO类型

    在如今深度学习的领域中,如果把数据比作老K,用以确保数据格式正确的就是Q,或者至少也得是J或者10,由此你可以看出它相当重要。在努力收集图像并注释所有的对象之后...

    AiTechYun
  • [Centos7]linux运行django项目报错no module named _ssl

    案例说明:在Django搭建的博客上进行邮件密码找回,当在输入框中输入邮件之后网页报错:no module named _ssl;此时进入到python环境,我...

    贰叁壹小窝
  • 【iOS】基于Realm数据库的记账软件--Realm数据库(一)

    </br> 以上,就是该项目的所有数据库表。实际项目会因业务需求,追加一些字段,但核心还是不变的。

    MapleYe

扫码关注云+社区

领取腾讯云代金券