Spring bean加载的顺序探究

目录

    • 前言
    • 例子代码和bean顺序
      • 改变全注解类加载顺序
      • bean 的依赖关系改变,被依赖的先加载
      • 自定义BeanFactoryPostProssort 提前获取某个bean
      • 按照refresh的finishBeanFactoryInitialization方法改变bean
      • BeanDefinitionRegistryPostProcessor改变beanDefinitions
      • @Configuration下@Bean从上到下的顺序
      • 实现ImportBeanDefinitionRegistrar接口自己注册
      • todo

前言

https://doctording.blog.csdn.net/article/details/144865082, 在认识AnnotationConfigApplicationContext加载流程的时候,实际上涉及到了一些顺序

  • BeanFactoryPostProcessor 是优先加载的,且有一系列顺序

观察refresh()方法的org.springframework.context.support.AbstractApplicationContext#finishBeanFactoryInitialization,可以看到普通bean加载是有一定顺序的, 如下

/*** Finish the initialization of this context's bean factory,* initializing all remaining singleton beans.*/
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {// Initialize conversion service for this context.if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {beanFactory.setConversionService(beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));}// Register a default embedded value resolver if no bean post-processor// (such as a PropertyPlaceholderConfigurer bean) registered any before:// at this point, primarily for resolution in annotation attribute values.if (!beanFactory.hasEmbeddedValueResolver()) {beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));}// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);for (String weaverAwareName : weaverAwareNames) {getBean(weaverAwareName);}// Stop using the temporary ClassLoader for type matching.beanFactory.setTempClassLoader(null);// Allow for caching all bean definition metadata, not expecting further changes.beanFactory.freezeConfiguration();// Instantiate all remaining (non-lazy-init) singletons.beanFactory.preInstantiateSingletons();
}

beanFactory.preInstantiateSingletons();按照beanDefinitions顺序加载

例子代码和bean顺序

如下定义两个@Configuration类,分别扫描不同的package
在这里插入图片描述

默认输出如下:

在这里插入图片描述

  1. 两个全注解类的bean先加载
  2. 然后分别是扫描各自扫描出来的bean的默认顺序加载

改变全注解类加载顺序

输出如下,符合预期
在这里插入图片描述

bean 的依赖关系改变,被依赖的先加载

  • depensOn
@Service
@DependsOn(value = "PBean2")
public class PBean1 {public PBean1() {System.out.println("PBean1");}
}
  • 构造函数注入
@Service
public class QBean1 {public QBean1(QBean2 qBean2) {System.out.println("QBean1:" + qBean2);}
}

如下:
在这里插入图片描述

自定义BeanFactoryPostProssort 提前获取某个bean

@Service
public class SelfBfpp implements BeanFactoryPostProcessor {public SelfBfpp() {System.out.println("SelfBfpp");}@Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {beanFactory.getBean("PBean2");}
}

在这里插入图片描述

按照refresh的finishBeanFactoryInitialization方法改变bean

例如实现了LoadTimeWeaverAware的bean先加载
在这里插入图片描述
补充:LoadTimeWeaverAware实际却是没碰到过,是Spring中用于在类加载时对指定的类型进行增强的工具,通常用于AspectJ的AOP实现。

BeanDefinitionRegistryPostProcessor改变beanDefinitions

  • 如下,直接不加载某个bean了
    在这里插入图片描述

  • 怪异的处理,然某个bean最后加载了
    在这里插入图片描述

@Configuration下@Bean从上到下的顺序

在这里插入图片描述

实现ImportBeanDefinitionRegistrar接口自己注册

全注解类加上@Import

@EnableAspectJAutoProxy
@Configuration
@ComponentScan("com.aop.order.p2")
@Import(SelfRegistor.class)
public class ConfigB {public ConfigB() {System.out.println("ConfigB");}}

然后自己注册,确保顺序

public class SelfRegistor implements ImportBeanDefinitionRegistrar {@Overridepublic void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {BeanDefinition beanDefinition4 = new GenericBeanDefinition();((GenericBeanDefinition) beanDefinition4).setBeanClass(QBean4.class);registry.registerBeanDefinition("q4", beanDefinition4);BeanDefinition beanDefinition3 = new GenericBeanDefinition();((GenericBeanDefinition) beanDefinition3).setBeanClass(QBean3.class);registry.registerBeanDefinition("q3", beanDefinition3);}
}

如下输出,先4后3
在这里插入图片描述

todo

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

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

相关文章

React 中hooks之useDeferredValue用法总结

目录 概述基本用法与防抖节流的区别使用场景区分过时内容最佳实践 概述 什么是 useDeferredValue? useDeferredValue 是 React 18 引入的新 Hook,用于延迟更新某个不那么重要的部分。它接收一个值并返回该值的新副本,新副本会延迟更新。这种延迟是有…

【博客之星2024年度总评选】年度回望:我的博客之路与星光熠熠

【个人主页】Francek Chen 【人生格言】征途漫漫,惟有奋斗! 【热门专栏】大数据技术基础 | 数据仓库与数据挖掘 | Python机器学习 文章目录 前言一、个人成长与盘点(一)机缘与开端(二)收获与分享 二、年度创…

R 语言科研绘图第 20 期 --- 箱线图-配对

在发表科研论文的过程中,科研绘图是必不可少的,一张好看的图形会是文章很大的加分项。 为了便于使用,本系列文章介绍的所有绘图都已收录到了 sciRplot 项目中,获取方式: R 语言科研绘图模板 --- sciRplothttps://mp.…

支持向量机SVM的应用案例

支持向量机(Support Vector Machine,SVM)是一种强大的监督学习算法,广泛应用于分类和回归任务。 基本原理 SVM的主要目标是周到一个最优的超平面,该超平面能够将不同类别的数据点尽可能分开,并且使离该超平面最近的数…

Ubuntu 24.04 LTS 更改软件源

Ubuntu 24.04 LTS 修改软件源

wps数据分析000002

目录 一、快速定位技巧 二、快速选中技巧 全选 选中部分区域 选中部分区域(升级版) 三、快速移动技巧 四、快速录入技巧 五、总结 一、快速定位技巧 ctrl→(上下左右)快速定位光标对准单元格的上下部分双击名称单元格中…

[gdb调试] gdb调试基础实践gdb指令汇总

​ 一. 参考资料 《C/C代码调试的艺术》 二. 调试过程 1. 编译: 使用Debug模式编译,或者使用Release模式编译加入-g参数,-g选项会在可执行文件中加入调试信息,这些信息包含了程序中的变量名、函数名、行号等,能让…

风吹字符起,诗意Linux:一场指令与自由的浪漫邂逅(上)

文章目录 前言一. 知识过渡文件的属性与类型路径 二. 基本指令ls:风起草长,窥见世界的全貌cd:穿梭路径间,漫步荒原的远方pwd:定位自我,荒原上的坐标mkdir:种下希望,创建属于自己的世…

知识图谱中的word2vec 技术是做什么的?

Word2Vec 是一种将单词转换为向量表示的技术,由 Google 在 2013 年提出。这项技术的核心思想是通过大规模文本数据训练神经网络模型,从而将单词映射到低维稠密的向量空间中。这些向量能够捕捉到单词之间的语义和语法关系,使得相似或相关的单词…

Chrome 132 版本新特性

Chrome 132 版本新特性 一、Chrome 132 版本浏览器更新 1. 在 iOS 上使用 Google Lens 搜索 在 Chrome 132 版本中,开始在所有平台上推出这一功能。 1.1. 更新版本: Chrome 126 在 ChromeOS、Linux、Mac、Windows 上:在 1% 的稳定版用户…

Kafka 日志存储 — 日志索引

每个日志分段文件对应两个索引文件:偏移量索引文件用来建立消息偏移量到物理地址之间的映射;时间戳索引文件根据指定的时间戳来查找对应的偏移量信息。 1 日志索引 Kafka的索引文件以稀疏索引的方式构造消息的索引。它并不保证每个消息在索引文件中都有…

消息队列篇--原理篇--RocketMQ(NameServer,Broker,单机上每秒处理数百万条消息性能)

1、概述 RocketMQ是阿里巴巴开源的一个分布式消息中间件,具有高吞吐量、低延迟和强一致性等特点。它特别适合大规模分布式系统的消息传递,广泛应用于电商、金融、物流等领域的实时数据处理和异步通信。 RocketMQ是用Java语言实现,在设计时参…

简述mysql 主从复制原理及其工作过程,配置一主两从并验证。

MySQL 主从同步是一种数据库复制技术,它通过将主服务器上的数据更改复制到一个或多个从服务器,实现数据的自动同步。 主从同步的核心原理是将主服务器上的二进制日志复制到从服务器,并在从服务器上执行这些日志中的操作。 MySQL主从同步是基…

Web前端开发技术之HTMLCSS知识点总结

学习路线 一、新闻网界面1. 代码示例2. 效果展示3. 知识点总结3.1 HTML标签和字符实体3.2 超链接、颜色描述与标题元素3.3 关于图片和视频标签:3.4 CSS引入方式3.5 CSS选择器优先级 二、flex布局1. 代码示例2. 效果展示3. 知识点总结3.1 span标签和flex容器的区别3.…

内存故障原因与诊断(Reasons and Diagnosis of Memory Failure)

内存故障原因与诊断 您是否曾遇到过电脑无法启动、黑屏、死机,或者系统卡顿的情况?这些问题看起来很复杂,实际上大多数都是内存故障引起的。内存是电脑的核心组成部分之一,任何小东西问题都可能导致系统死机,严重时甚…

vulnhub靶机(ReconForce)

一.信息收集: 使用nmap进行端口扫描,发现其开放了ftp,http,ssh服务 nmap -sS -O -sV -p- 192.168.80.142访问其80端口发现是一个网页,点击TroubleShoot后发现其需要登录 在去尝试使用ftp的匿名登录发现无法执行任何命令,发现了他的欢迎语有点特别 在扫描目录后没有发现什么有…

54,【4】BUUCTF WEB GYCTF2020Ezsqli

进入靶场 吓我一跳,但凡放个彭于晏我都不说啥了 提交个1看看 1 and 11 1# 还尝试了很多,不过都被过滤了,头疼 看看别人的WP 竟然要写代码去跑!!!,不会啊,先用别人的代码吧&#xf…

vue2使用flv.js在浏览器打开flv格式视频

组件地址&#xff1a;GitHub - bilibili/flv.js: HTML5 FLV Player flv.js 仅支持 H.264 和 AAC/MP3 编码的 FLV 文件。如果视频文件使用了其他编码格式就打不开。 flv.vue <template><div><el-dialog :visible.sync"innerVisibleFlv" :close-on-pre…

Git原理与应用(三)【远程操作 | 理解分布式 | 推送拉取远程仓库 | 标签管理】

Git 理解分布式版本控制系统远程仓库新建远程仓库克隆远程仓库向远程仓库推送配置Git忽略特殊文件 标签管理理解标签创建标签操作标签删除标签 理解分布式版本控制系统 我们⽬前所说的所有内容&#xff08;工作区&#xff0c;暂存区&#xff0c;版本库等等&#xff09;&#x…

网络安全:信息时代的守护者

随着互联网的快速发展&#xff0c;网络安全问题日益成为全球关注的焦点。无论是个人用户、企业组织还是政府部门&#xff0c;网络安全都已成为保障信息安全、保护隐私、确保社会秩序的基石。在这个数字化时代&#xff0c;如何应对复杂多变的网络安全威胁&#xff0c;成为了我们…