Mr. Cappuccino的第63杯咖啡——Spring之AnnotationConfigApplicationContext源码分析

Spring之AnnotationConfigApplicationContext源码分析

    • 源码分析

源码分析

以上一篇文章《Spring之Bean的生命周期》的代码进行源码分析

AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringConfig02.class);
LifeCycleBean lifeCycleBean = applicationContext.getBean("lifeCycleBean", LifeCycleBean.class);
System.out.println("-----------------------------------");
System.out.println("LifeCycleBean " + lifeCycleBean);
System.out.println("-----------------------------------");
applicationContext.close();

new AnnotationConfigApplicationContext(SpringConfig02.class)

AnnotationConfigApplicationContext.java

在这里插入图片描述

AbstractApplicationContext.java

@Override
public void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {// Prepare this context for refreshing.// 容器刷新前的准备工作,例如对系统属性、环境变量进行准备及验证prepareRefresh();// Tell the subclass to refresh the internal bean factory.// 初始化BeanFactoryConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();// Prepare the bean factory for use in this context.// 对BeanFactory进行属性填充及功能填充,例如添加某些BeanPostProcessor以实现某些功能(ApplicationContextAwareProcessor)prepareBeanFactory(beanFactory);try {// Allows post-processing of the bean factory in context subclasses.// 空方法,用于子类实现扩展功能postProcessBeanFactory(beanFactory);// Invoke factory processors registered as beans in the context.// 执行BeanFactoryPostProcessor,例如ConfigurationClassPostProcessor、EventListenerMethodProcessor以及某些自定义的BeanFactoryPostProcessor// ConfigurationClassPostProcessor用于处理配置类,会将配置类中需要注册的Bean对象的元数据解析并存入beanDefinitionMap集合中invokeBeanFactoryPostProcessors(beanFactory);// Register bean processors that intercept bean creation.// 注册BeanPostProcessor,例如AutowiredAnnotationBeanPostProcessor、CommonAnnotationBeanPostProcessor以及某些自定义的BeanPostProcessorregisterBeanPostProcessors(beanFactory);// Initialize message source for this context.// 初始化消息资源,国际化处理initMessageSource();// Initialize event multicaster for this context.// 初始化消息多播器initApplicationEventMulticaster();// Initialize other special beans in specific context subclasses.// 空方法,用于子类实现扩展功能onRefresh();// Check for listener beans and register them.// 注册所有的ApplicationListener到消息多播器registerListeners();// Instantiate all remaining (non-lazy-init) singletons.// 实例化、初始化剩下的非懒加载的单例对象finishBeanFactoryInitialization(beanFactory);// Last step: publish corresponding event.// 完成刷新动作,启动LifecycleProcessor,发布ContextRefreshedEvent事件finishRefresh();}catch (BeansException ex) {if (logger.isWarnEnabled()) {logger.warn("Exception encountered during context initialization - " +"cancelling refresh attempt: " + ex);}// Destroy already created singletons to avoid dangling resources.// 销毁已创建的单例对象destroyBeans();// Reset 'active' flag.cancelRefresh(ex);// Propagate exception to caller.throw ex;}finally {// Reset common introspection caches in Spring's core, since we// might not ever need metadata for singleton beans anymore...resetCommonCaches();}}
}

BeanFactory中两个重要的对象

DefaultListableBeanFactory.java

/** Map of bean definition objects, keyed by bean name. */
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);

DefaultSingletonBeanRegistry.java

/** Cache of singleton objects: bean name to bean instance. */
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);

Debug源码分析

在这里插入图片描述
在这里插入图片描述

register(componentClasses):注册指定的配置类SpringConfig02到beanDefinitionMap集合中

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

invokeBeanFactoryPostProcessors(beanFactory):创建BeanFactoryPostProcessor接口相关实现类的实例对象并存入singletonObjects集合中;执行BeanFactoryPostProcessor接口相关实现类的方法,通过ConfigurationClassPostProcessor处理配置类中需要注册的bean对象,并将bean对象注册到beanDefinitionMap集合中。

在这里插入图片描述

registerBeanPostProcessors(beanFactory):注册BeanPostProcessor接口相关实现类,创建BeanPostProcessor接口相关实现类的实例对象并存入singletonObjects集合中

在这里插入图片描述
在这里插入图片描述

finishBeanFactoryInitialization(beanFactory):实例化、初始化剩下的非懒加载的单例对象并存入singletonObjects集合中

在这里插入图片描述

beanFactory.preInstantiateSingletons():提前加载单例对象


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/94596.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

uniapp编写微信小程序遇到的坑总结

1、阻止事件冒泡 使用uniapp开发微信小程序的时候&#xff0c;发现使用click.stop来阻止事件冒泡没有作用&#xff0c;点击了之后发现仍然会触发父组件或者祖先组件的事件。 在网上查阅&#xff0c;发现使用tap.stop才能阻止事件冒泡。 2、二维码生成 在网上找了很多&…

MQTT协议-EMQX技术文档-spring-boot整合使用--发送接收-消费

概念先行&#xff1a; mqtt与mq的关系 MQTT&#xff08;Message Queuing Telemetry Transport&#xff09;是一种基于发布/订阅模式的通信协议&#xff0c;它与MQ&#xff08;Message Queue&#xff0c;消息队列&#xff09;有一定的关联&#xff0c;但二者并不完全相同。 M…

重发布 路由策略

[r4]ip ip_prefix 15 permit 192.168.3.0 24. 根据序号插入规则 [r4]undo ip-prefix aa index 15. 删除规则 [r4]ip ip-prefix aa permit 192.168.3.0 24 less- equal 28 抓取目标网段为3.0掩码长度为24到28的路由 [r4]ip ip-prefix aa permit 192.168.3.0 24 greate…

【K8S系列】Weave Net 故障排除的常见问题和解决方案

写在前面 当使用 Weave Net 进行容器网络配置时&#xff0c;可能会遇到一些常见的故障情况。以下是一些常见问题及其解决方案&#xff1a; 问题列表 1 节点无法加入 Weave Net 网络 解决方案 检查节点之间的网络连通性&#xff0c;确保可以通过 IP 地址相互访问。 检查节点的…

大模型时代,图像描述生成(image caption)怎么走?

背景 Image caption是计算机视觉研究领域中的一个重要分支&#xff0c;其主要目标是根据输入的图像信息&#xff0c;生成相应的文字描述&#xff0c;从而完成对图像内容的准确描述。对于图像描述任务而言&#xff0c;最关键的是能够将图片中的信息以清晰准确的文字形式展现出来…

基于python+MobileNetV2算法模型实现一个图像识别分类系统

一、目录 算法模型介绍模型使用训练模型评估项目扩展 二、算法模型介绍 图像识别是计算机视觉领域的重要研究方向&#xff0c;它在人脸识别、物体检测、图像分类等领域有着广泛的应用。随着移动设备的普及和计算资源的限制&#xff0c;设计高效的图像识别算法变得尤为重要。…

Android DataStore:安全存储和轻松管理数据

关于作者&#xff1a;CSDN内容合伙人、技术专家&#xff0c; 从零开始做日活千万级APP。 专注于分享各领域原创系列文章 &#xff0c;擅长java后端、移动开发、人工智能等&#xff0c;希望大家多多支持。 目录 一、导读二、概览三、使用3.1 Preferences DataStore添加依赖数据读…

解决校园网使用vmware桥接模式,虚拟机与物理机互相ping通,但是虚拟机ping不通百度的问题

遇到的问题 使用校园网时&#xff0c;桥接模式下&#xff0c;物理机可以ping通虚拟机&#xff0c;但是虚拟机ping不通主机 解决方法 在物理机中查看网络相关信息 ipconfig 修改虚拟机网卡信息 vim /etc/sysconfig/network-scripts/ifcfg-ens33 注意 /ifcfg-ens33需要根据…

批次效应分析

写在前面 批次效应分析,在医学芯片研究中,使用不同芯片进行分析时常用的数据处理方式,但是很多同学处理后的数据,存在不满意的情况。因此,到处咨询,各种查教程。今天,使用简短的时间分享该数据处理教程。 最终分析结果 欢迎投稿 小杜一直在分享自己平时学习笔记,因此…

Redis——三个特殊的数据类型+事务

概述 全称为远程字典服务。 Redis——基础篇(包含redis在云服务上的docker化安装和连接以及常用命令)_连接docker中的redis_北岭山脚鼠鼠的博客-CSDN博客 Redis能干什么&#xff1f; 1.内存存储、持久化&#xff0c;内存中是断电即失&#xff0c;因此持久化很重要&#xff…

golang中使用chan控制协程并发简单事例

func main() {processNum : 5ch : make(chan struct{}, processNum)for true {ch <- struct{}{}go func() {defer func() {<-ch}()fmt.Println("我是协程", time.Now().UnixNano())time.Sleep(time.Second * 5)}()} } 可以看到&#xff0c;这里每5s会执行一次带…

STM32/AT32 MCO管脚输出时钟配置

前言&#xff1a;最近在学以太网通讯&#xff0c;发现RMII接口配置的时钟管脚有MCU自己输出&#xff0c;想要看看是怎么输出的&#xff0c;对此进行记录 1、交接项目项目上使用的是PA8管脚来输出时钟50MHZ&#xff0c;提供给上面refclk。 先看手册 PA8的复用功能具备将MCU时钟…

拒绝摆烂!C语言练习打卡第三天

&#x1f525;博客主页&#xff1a;小王又困了 &#x1f4da;系列专栏&#xff1a;每日一练 &#x1f31f;人之为学&#xff0c;不日近则日退 ❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 目录 一、选择题 &#x1f4dd;1.第一题 &#x1f4dd;2.第二题 &#x1f4…

java练习3.快速查找

题目: 数组 arr[6,1,3,7,9,8,5,4,2],用快速排序进行升序排序. import java.util.Random;public class recursionDemo {public static void main(String[] args) {/*快速排序:* 第一轮:以0索引为基准数,确定基准数在数组正确的位置,* 比基准数小的放到左边,比基准数大的放在右边…

【Linux】【驱动】应用层和驱动层传输数据

【Linux】【驱动】应用层和驱动层传输数据 绪论1.如果我在应用层使用系统0 对设备节点进行打开&#xff0c;关闭&#xff0c;读写等操作会发生什么呢? 2 我们的应用层和内核层是不能直接进行数据传输的3 驱动部分的代码4 应用代码5 编译以及运行代码 绪论 Linux一切皆文件! 文…

Maven自定义脚手架(多module模块)+自定义参数

脚手架 视频教程&#xff1a; Maven保姆级教程 脚手架是一个项目模板&#xff0c;包含常用的工程结构、代码。 1 自定义脚手架 脚手架创建的步骤如下&#xff0c;先创建一个工程&#xff0c;把常用的代码写好&#xff0c;进入工程根目录&#xff0c;进行如下操作&#xff1a; …

Angular安全专辑之二——‘unsafe-eval’不是以下内容安全策略中允许的脚本源

一&#xff1a;错误出现 这个错误的意思是&#xff0c;拒绝将字符串评估为 JavaScript&#xff0c;因为‘unsafe-eval’不是以下内容安全策略中允许的脚本源。 二&#xff1a;错误场景 testEval() {const data eval("var sum2 new Function(a, b, return a b); sum2(em…

使用 PyTorch 进行高效图像分割:第 1 部分

一、说明 在这个由 4 部分组成的系列中&#xff0c;我们将使用 PyTorch 中的深度学习技术从头开始逐步实现图像分割。我们将在本文中从图像分割所需的基本概念和想法开始本系列。 图1&#xff1a;宠物图像及其分割掩码&#xff08;来源&#xff1a;牛津-IIIT宠物数据集) 图像分…

DAY2,ARM(特殊功能寄存器,数据操作指令,跳转指令)

1.cmp、sub、b指令的使用&#xff1b; 代码&#xff1a; .text .global _start _start:mov r0,#9mov r1,#15loop:cmp r0,r1beq stopsubcc r1,r1,r0subhi r0,r0,r1b loopstop:b stop .end结果&#xff1a; 2.汇编指令计算1~100之间和&#xff1b; 代码&#xff1a; .text .gl…

Oracle执行计划

Oracle执行计划 1. 什么是执行计划Oracle explain使用3. Explain执行顺序 1. 什么是执行计划 执行计划是一条查询语句在Oracle中的执行过程或访问路径的描述。 执行计划描述了SQL引擎为执行SQL语句进行的操作&#xff1b;分析SQL语句相关的性能问题或仅仅质疑查询优化器的决定…