Spring 中如何控制 Bean 的加载顺序?
如果你脱口而出说添加 @Order 注解或者是实现 Ordered 接口,那么恭喜,你掉坑了。
一 @Order 注解和 Ordered 接口
在 Spring 框架中,@Order 是一个非常实用的元注解,它位于 spring-core 包下,主要用于控制某些特定上下文中组件的执行顺序或排序,但它并不直接控制 Bean 的初始化顺序。
1.1 用途
@Order 注解或者是 Ordered 接口,常见的用途主要是两种:
-
定义执行顺序:当多个组件(如拦截器、过滤器、监听器等)需要按照特定的顺序执行时,
@Order注解可以用来指定这些组件的执行优先级。数值越小,优先级越高,相应的组件会更早被执行或被放置在集合的前面(@Order注解接受一个整数值,这个值可以是负数、零或正数。Spring 框架提供了Ordered.HIGHEST_PRECEDENCE(默认最低优先级)和Ordered.LOWEST_PRECEDENCE(默认最高优先级)常量,分别对应于 Integer.MIN_VALUE和 Integer.MAX_VALUE,可以方便地设定优先级。)。 -
集合排序:当相同类型的组件被自动装配到一个集合中时,
@Order注解会影响它们在这个集合中的排列顺序。
1.2 使用场景
经典使用场景。
拦截器排序
在 Spring MVC 中,可以使用 @Order 来控制拦截器的执行顺序。
Spring Security Filters(过滤器)
在 Spring Security 中,过滤器链的顺序通过 @Order 来定义,确保正确的安全处理流程。这个在松哥最近的教程中和大家详细介绍过了。

Event Listeners(事件监听器)
当有多个监听同一事件的监听器时,可以通过 @Order 来控制它们的触发顺序。
Bean 的集合注入
当一个 Bean 依赖于一个特定类型的 Bean 集合时,带有 @Order 注解的 Bean 将按照指定顺序被注入。
可以看到,@Order 注解的使用场景中,主要是相同类型的 Bean 存在多个时,这多个 Bean 的执行顺序可以通过 @Order 注解或者实现 Ordered 接口来确定。
但是!!!
@Order 注解不控制初始化和加载:@Order 注解不直接影响 Bean 的创建和初始化过程,这些由 Spring IoC 容器基于依赖关系和配置来决定。Spring IoC 容器根据依赖关系图来决定 Bean 的初始化顺序,而不是依据 @Order 注解。依赖关系决定了哪些 Bean 需要在其他 Bean 初始化之前被创建。
二 如何设置 Bean 的加载顺序?
有两种方式来设置 Bean 的加载顺序。
2.1 @DependsOn
@DependsOn 是 Spring 框架提供的一个注解,用于指示 Spring 容器在初始化一个 Bean 之前,必须先初始化其依赖的其他 Bean。这个注解可以帮助解决 Bean 间的依赖关系,确保依赖的 Bean 已经准备就绪。
@DependsOn 可以放在任何一个 Spring 管理的 Bean 定义上,包括但不限于配置类、服务类、数据访问对象等。其语法如下:
@DependsOn({"beanName1", "beanName2", ...})
public class MyBean {// ...
}
在这个例子中,MyBean 类声明了它依赖于名为 beanName1 和 beanName2 的 Bean。这意味着,当 Spring 容器创建 MyBean 的实例时,它会首先确保 beanName1 和 beanName2 已经被正确初始化。
相关的源码在 AbstractBeanFactory#doGetBean 方法中:

在创建的 Bean 的时候,先检查该 Bean 是否依赖了其他 Bean,如果依赖了,则先把其他 Bean 创建出来,然后再继续创建当前 Bean,这样就确保了 Bean 的加载顺序。
如果小伙伴们对这块的完整流程感兴趣,可以看松哥录制的 Spring源码分析。
2.2 BeanFactoryPostProcessor
第二种方式就是利用 BeanFactoryPostProcessor,BeanFactoryPostProcessor 的执行时机比较早,从下面这张流程图中可以看到,BeanFactoryPostProcessor 在正常的 Bean 初始化之前就执行了。

那么对于想要提前初始化的 Bean,我们可以在 BeanFactoryPostProcessor 中手动调用,类似下面这样:
@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {@Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {//想要提前初始化的 Bean 在这里执行beanFactory.getBean("serviceB");}
}
三 小结
多个相同类型的 Bean 该如何确保其执行顺序?这个靠 @Order 注解或者 Ordered 接口来解决。但是这两者并不能解决 Bean 的加载顺序。Bean 的加载顺序有两种方式可以调整:
- 通过 @DependsOn 注解加载。
- 手动在 BeanFactoryPostProcessor#postProcessBeanFactory 方法中提前调用 getBean 方法去初始化 Bean。
如果小伙伴们想要彻底掌握 Spring 源码,那么不妨看看松哥录制的 Spring 源码视频教程。
相关文章:
Spring 中如何控制 Bean 的加载顺序?
如果你脱口而出说添加 Order 注解或者是实现 Ordered 接口,那么恭喜,你掉坑了。 一 Order 注解和 Ordered 接口 在 Spring 框架中,Order 是一个非常实用的元注解,它位于 spring-core 包下,主要用于控制某些特定上下文…...
【学习笔记】Windows GDI绘图(十)Graphics详解(中)
文章目录 Graphics的方法AddMetafileComment添加注释BeginContainer和EndContainer新建、还原图形容器不指定指定源与目标矩形指定源与目标矩形 Clear清空并填充指定颜色CopyFromScreen截图CopyPixelOperation DrawImage绘制图像DrawImage的GraphicsDrawImageAbort回调ExcludeC…...
web学习笔记(六十二)
目录 1.键盘事件 2.KeepAlive 3.组件传值 3.1 兄弟组件传值 3.2 组件树传值 3.3 发布订阅者传值 1.键盘事件 keydown表示键盘事件,在不加修饰符的情况下,点击键盘上的任意位置都可以触发键盘事件, <template><div><!--…...
每天CTF小练一点--ctfshow年CTF
初一 题目: 2023是兔年,密码也是。聪明的小伙伴们,你能破解出下面的密码吗? 感谢大菜鸡师傅出题 flag格式是ctfshow{xxxxxx}.或许密码也有密码。 密文是: U2FsdGVkX1M7duRffUvQgJlESPfOTV2i4TJpc9YybgZ9ONmPk/RJje …...
Java Set接口 - TreeSet类
TreeSet 是 Java 集合框架中的一个类,它实现了 NavigableSet 接口,而 NavigableSet 是 SortedSet 接口的一个子接口。TreeSet 基于红黑树(一种自平衡的二叉搜索树)实现,因此它可以保证集合中的元素以升序排列。 以下是…...
css 理解了原理,绘制三角形就简单了
1.border-位置 注意:border-bottom/up/right/left 主要是以三角形的结构搭建而成,而border也是如此。而且从边框的外围开始计算像素尺寸。在理解了这一点之后,绘制三角形就简单多了。 1.transparent 注意:该属性主要是颜色透明…...
【JavaEE进阶】——MyBatis操作数据库 (#{}与${} 以及 动态SQL)
目录 🚩#{}和${} 🎈#{} 和 ${}区别 🎈${}使用场景 📝排序功能 📝like 查询 🚩数据库连接池 🎈数据库连接池使⽤ 🚩MySQL开发企业规范 🚩动态sql 🎈…...
电阻应变片的结构
电阻应变片的结构 常用的电阻应变片有金属应变片和半导体应变片两种。金属应变片分为体型和薄膜型。半导体应变片常见的有体型、薄膜型、扩散型、外延型、PN结及其他形式。图2—2所示为工程常见的应变片实物。 电阻应变片的典型结构如图2—3所示。它由敏感栅、基底、覆盖层和引…...
云原生时代:从 Jenkins 到 Argo Workflows,构建高效 CI Pipeline
作者:蔡靖 Argo Workflows Argo Workflows [ 1] 是用于在 Kubernetes 上编排 Job 的开源的云原生工作流引擎。可以轻松自动化和管理 Kubernetes 上的复杂工作流程。适用于各种场景,包括定时任务、机器学习、ETL 和数据分析、模型训练、数据流 pipline、…...
【数据库系统概论】事务
概述 在数据库系统中,事务(Transaction)是指一组作为单个逻辑工作单元执行的操作。这些操作要么全部成功(提交),要么全部失败(回滚)。事务的主要目的是确保数据库的完整性和一致性&…...
C++-排序算法详解
目录 一. 冒泡排序: 二. 插入排序: 三. 快速排序: 四. 选择排序 五, 归并排序 六, 堆排序. 排序算法是一种将一组数据按照特定顺序(如升序或降序)进行排列的算法。 其主要目的是对一组无序的数据进行整理&#…...
Kotlin 引用(双冒号::)
文章目录 双冒号::引用函数普通函数成员函数类构造函数 引用变量(很少用)普通变量成员变量 双冒号:: Kotlin 中可以使用双冒号::对某一变量、函数进行引用。 Note:MyClass::class可用于获取KClass<MyClass>,此时的双冒号::…...
C++ day3练习
设计一个Per类,类中包含私有成员:姓名、年龄、指针成员身高、体重,再设计一个Stu类,类中包含私有成员:成绩、Per类对象p1,设计这两个类的构造函数、析构函数。 #include <iostream>using namespace std;class Per{private:…...
命令模式(行为型)
目录 一、前言 二、命令模式 三、总结 一、前言 命令模式(Command Pattern)是一种行为型设计模式,命令模式将一个请求封装为一个对象,从而可以用不同的请求对客户进行参数化;对请求排队或记录请求日志,以…...
韩雪医生针药结合效果好 患者赠送锦旗表感谢
任先生长年献血身体出现不适,身上多处发黑发冷,伴随疼痛,而且还有慢性腹泻的症状。他曾前往苏州各大医馆做过检查,均查不出异常,但身体确实不舒服,面色晦暗。 后来他来到李良济,求诊于韩雪医生。…...
【队列、堆、栈 解释与区分】
文章目录 概要队列(Queue)定义特性应用场景 堆(Heap)定义特性应用场景 栈(Stack)定义特性应用场景 总结 概要 队列、堆和栈是三种常见的数据结构,它们各自具有不同的特性和应用场景。下面是对这…...
NTP网络时间服务器_安徽京准电钟
NTP网络时间服务器_安徽京准电钟 NTP网络时间服务器_安徽京准电钟 概述 NTP网络时间服务器是一款支持NTP和SNTP网络时间同步协议,高精度、大容量、高品质的高科技时钟产品。 NTP网络时间服务器设备采用冗余架构设计,高精度时钟直接来源于北斗、GPS系统中…...
Java:爬虫框架
一、Apache Nutch2 【参考地址】 Nutch 是一个开源Java 实现的搜索引擎。它提供了我们运行自己的搜索引擎所需的全部工具。包括全文搜索和Web爬虫。 Nutch 致力于让每个人能很容易, 同时花费很少就可以配置世界一流的Web搜索引擎. 为了完成这一宏伟的目标, Nutch必须能够做到…...
ChatGPT基本原理详细解说
ChatGPT基本原理详细解说 引言 在人工智能领域,自然语言处理(NLP)一直是研究的热点之一。随着技术的发展,我们见证了从简单的聊天机器人到复杂的语言模型的演变。其中,ChatGPT作为一项突破性技术,以其强大…...
Java日期时间处理深度解析:从Date、Calendar到SimpleDateFormat
粉丝福利:微信搜索「万猫学社」,关注后回复「电子书」,免费获取12本Java必读技术书籍。 Java中的日期和时间处理 在Java中,日期和时间的处理一直是一个复杂而繁琐的任务。那么,为什么会这样呢?让我们先来看…...
接口测试中缓存处理策略
在接口测试中,缓存处理策略是一个关键环节,直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性,避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明: 一、缓存处理的核…...
逻辑回归:给不确定性划界的分类大师
想象你是一名医生。面对患者的检查报告(肿瘤大小、血液指标),你需要做出一个**决定性判断**:恶性还是良性?这种“非黑即白”的抉择,正是**逻辑回归(Logistic Regression)** 的战场&a…...
CentOS下的分布式内存计算Spark环境部署
一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架,相比 MapReduce 具有以下核心优势: 内存计算:数据可常驻内存,迭代计算性能提升 10-100 倍(文档段落:3-79…...
CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云
目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...
uniapp中使用aixos 报错
问题: 在uniapp中使用aixos,运行后报如下错误: AxiosError: There is no suitable adapter to dispatch the request since : - adapter xhr is not supported by the environment - adapter http is not available in the build 解决方案&…...
【Oracle】分区表
个人主页:Guiat 归属专栏:Oracle 文章目录 1. 分区表基础概述1.1 分区表的概念与优势1.2 分区类型概览1.3 分区表的工作原理 2. 范围分区 (RANGE Partitioning)2.1 基础范围分区2.1.1 按日期范围分区2.1.2 按数值范围分区 2.2 间隔分区 (INTERVAL Partit…...
什么是Ansible Jinja2
理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具,可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板,允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板,并通…...
2023赣州旅游投资集团
单选题 1.“不登高山,不知天之高也;不临深溪,不知地之厚也。”这句话说明_____。 A、人的意识具有创造性 B、人的认识是独立于实践之外的 C、实践在认识过程中具有决定作用 D、人的一切知识都是从直接经验中获得的 参考答案: C 本题解…...
CVE-2020-17519源码分析与漏洞复现(Flink 任意文件读取)
漏洞概览 漏洞名称:Apache Flink REST API 任意文件读取漏洞CVE编号:CVE-2020-17519CVSS评分:7.5影响版本:Apache Flink 1.11.0、1.11.1、1.11.2修复版本:≥ 1.11.3 或 ≥ 1.12.0漏洞类型:路径遍历&#x…...
【SpringBoot自动化部署】
SpringBoot自动化部署方法 使用Jenkins进行持续集成与部署 Jenkins是最常用的自动化部署工具之一,能够实现代码拉取、构建、测试和部署的全流程自动化。 配置Jenkins任务时,需要添加Git仓库地址和凭证,设置构建触发器(如GitHub…...
