当前位置:首页 > 科技  > 软件

Spring 中如何控制 Bean 的加载顺序?

来源: 责编: 时间:2024-05-29 17:32:13 101观看
导读如果你脱口而出说添加 @Order 注解或者是实现 Ordered 接口,那么恭喜,你掉坑了。一、@Order 注解和 Ordered 接口在 Spring 框架中,@Order 是一个非常实用的元注解,它位于 spring-core 包下,主要用于控制某些特定上下文中

如果你脱口而出说添加 @Order 注解或者是实现 Ordered 接口,那么恭喜,你掉坑了。DLG28资讯网——每日最新资讯28at.com

一、@Order 注解和 Ordered 接口

在 Spring 框架中,@Order 是一个非常实用的元注解,它位于 spring-core 包下,主要用于控制某些特定上下文中组件的执行顺序或排序,但它并不直接控制 Bean 的初始化顺序。DLG28资讯网——每日最新资讯28at.com

1.1 用途

@Order 注解或者是 Ordered 接口,常见的用途主要是两种:DLG28资讯网——每日最新资讯28at.com

  • 定义执行顺序:当多个组件(如拦截器、过滤器、监听器等)需要按照特定的顺序执行时,@Order 注解可以用来指定这些组件的执行优先级。数值越小,优先级越高,相应的组件会更早被执行或被放置在集合的前面(@Order 注解接受一个整数值,这个值可以是负数、零或正数。Spring 框架提供了 Ordered.HIGHEST_PRECEDENCE(默认最低优先级)和 Ordered.LOWEST_PRECEDENCE(默认最高优先级)常量,分别对应于  Integer.MIN_VALUE和 Integer.MAX_VALUE,可以方便地设定优先级。)。
  • 集合排序:当相同类型的组件被自动装配到一个集合中时,@Order 注解会影响它们在这个集合中的排列顺序。

1.2 使用场景

经典使用场景。DLG28资讯网——每日最新资讯28at.com

拦截器排序

在 Spring MVC 中,可以使用 @Order 来控制拦截器的执行顺序。DLG28资讯网——每日最新资讯28at.com

Spring Security Filters(过滤器)

在 Spring Security 中,过滤器链的顺序通过 @Order 来定义,确保正确的安全处理流程。这个在松哥最近的教程中和大家详细介绍过了。DLG28资讯网——每日最新资讯28at.com

图片图片DLG28资讯网——每日最新资讯28at.com

Event Listeners(事件监听器)

当有多个监听同一事件的监听器时,可以通过 @Order 来控制它们的触发顺序。DLG28资讯网——每日最新资讯28at.com

Bean 的集合注入

当一个 Bean 依赖于一个特定类型的 Bean 集合时,带有 @Order 注解的 Bean 将按照指定顺序被注入。DLG28资讯网——每日最新资讯28at.com

可以看到,@Order 注解的使用场景中,主要是相同类型的 Bean 存在多个时,这多个 Bean 的执行顺序可以通过 @Order 注解或者实现 Ordered 接口来确定。DLG28资讯网——每日最新资讯28at.com

但是!!!DLG28资讯网——每日最新资讯28at.com

@Order 注解不控制初始化和加载:@Order 注解不直接影响 Bean 的创建和初始化过程,这些由 Spring IoC 容器基于依赖关系和配置来决定。Spring IoC 容器根据依赖关系图来决定 Bean 的初始化顺序,而不是依据 @Order 注解。依赖关系决定了哪些 Bean 需要在其他 Bean 初始化之前被创建。DLG28资讯网——每日最新资讯28at.com

二、如何设置 Bean 的加载顺序?

有两种方式来设置 Bean 的加载顺序。DLG28资讯网——每日最新资讯28at.com

2.1 @DependsOn

@DependsOn 是 Spring 框架提供的一个注解,用于指示 Spring 容器在初始化一个 Bean 之前,必须先初始化其依赖的其他 Bean。这个注解可以帮助解决 Bean 间的依赖关系,确保依赖的 Bean 已经准备就绪。DLG28资讯网——每日最新资讯28at.com

@DependsOn 可以放在任何一个 Spring 管理的 Bean 定义上,包括但不限于配置类、服务类、数据访问对象等。其语法如下:DLG28资讯网——每日最新资讯28at.com

@DependsOn({"beanName1", "beanName2", ...})public class MyBean {    // ...}

在这个例子中,MyBean 类声明了它依赖于名为 beanName1 和 beanName2 的 Bean。这意味着,当 Spring 容器创建 MyBean 的实例时,它会首先确保 beanName1 和 beanName2 已经被正确初始化。DLG28资讯网——每日最新资讯28at.com

相关的源码在 AbstractBeanFactory#doGetBean 方法中:DLG28资讯网——每日最新资讯28at.com

图片图片DLG28资讯网——每日最新资讯28at.com

在创建的 Bean 的时候,先检查该 Bean 是否依赖了其他 Bean,如果依赖了,则先把其他 Bean 创建出来,然后再继续创建当前 Bean,这样就确保了 Bean 的加载顺序。DLG28资讯网——每日最新资讯28at.com

如果小伙伴们对这块的完整流程感兴趣,可以看松哥录制的 Spring源码分析。DLG28资讯网——每日最新资讯28at.com

2.2 BeanFactoryPostProcessor

第二种方式就是利用 BeanFactoryPostProcessor,BeanFactoryPostProcessor 的执行时机比较早,从下面这张流程图中可以看到,BeanFactoryPostProcessor 在正常的 Bean 初始化之前就执行了。DLG28资讯网——每日最新资讯28at.com

图片图片DLG28资讯网——每日最新资讯28at.com

那么对于想要提前初始化的 Bean,我们可以在 BeanFactoryPostProcessor 中手动调用,类似下面这样:DLG28资讯网——每日最新资讯28at.com

@Componentpublic class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {    @Override    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {        //想要提前初始化的 Bean 在这里执行        beanFactory.getBean("serviceB");    }}

三、小结

多个相同类型的 Bean 该如何确保其执行顺序?这个靠 @Order 注解或者 Ordered 接口来解决。但是这两者并不能解决 Bean 的加载顺序。Bean 的加载顺序有两种方式可以调整:DLG28资讯网——每日最新资讯28at.com

  1. 通过 @DependsOn 注解加载。
  2. 手动在 BeanFactoryPostProcessor#postProcessBeanFactory 方法中提前调用 getBean 方法去初始化 Bean。

如果小伙伴们想要彻底掌握 Spring 源码,那么不妨看看松哥录制的 Spring 源码视频教程。DLG28资讯网——每日最新资讯28at.com

这套视频教程基于目前最新的 Spring6 录制,一共有 204 集约 40 个小时,从 Spring 基本用法讲起,一直讲到源码分析。DLG28资讯网——每日最新资讯28at.com

以下是完整视频目录:DLG28资讯网——每日最新资讯28at.com

├── 01.基础用法│   ├── 01.IoC基础│   │   ├── 01.Spring框架介绍-核心容器.mp4│   │   ├── 02.Spring框架介绍-数据访问和通信.mp4│   │   ├── 03.Spring框架介绍-Web模块.mp4│   │   ├── 04.Spring框架介绍-AOP和测试.mp4│   │   ├── 05.什么是IoC.mp4│   │   ├── 06.自定义一个简单的IoC.mp4│   │   ├── 07.向Spring容器注册Bean.mp4│   │   ├── 08.从Spring容器获取Bean.mp4│   │   ├── 09.id属性和name属性.mp4│   │   ├── 10.基本属性注入.mp4│   │   ├── 11.复杂属性注入.mp4│   │   ├── 12.构造器注入.mp4│   │   ├── 13.p名称空间注入.mp4│   │   ├── 14.属性自动注入.mp4│   │   ├── 15.配置文件加载.mp4│   │   ├── 16.Java代码配置IoC.mp4│   │   ├── 17.BeanName自动生成原理.mp4│   │   ├── 18.id和name属性处理原理.mp4│   │   ├── 19.Bean 的作用域.mp4│   │   ├── 20.singleton 和 prototype 的区别.mp4│   │   ├── 21.条件注解详解.mp4│   │   ├── 22.多环境切换.mp4│   │   ├── 23.Profile原理分析.mp4│   │   ├── 24.自定义Profile.mp4│   │   ├── 25.Bean的依赖关系.mp4│   │   ├── 26.FactoryBean用法.mp4│   │   ├── 27.抽取Bean的公共属性.mp4│   │   ├── 28.父子容器问题.mp4│   │   ├── 29.@Configuration注解的作用.mp4│   │   ├── 30.Bean自动扫描.mp4│   │   └── 31.属性值注入.mp4│   ├── 02.AOP基础│   │   ├── 01.静态代理.mp4│   │   ├── 02.编译时增强和运行时增强.mp4│   │   ├── 03.编译时增强.mp4│   │   ├── 04.运行时增强-JDK.mp4│   │   ├── 05.运行时增强-CGLIB.mp4│   │   ├── 06.什么是Spring AOP.mp4│   │   ├── 07.SpringAOP和AspectJAOP.mp4│   │   ├── 08.Spring AOP核心概念.mp4│   │   ├── 09.Spring AOP入门用法.mp4│   │   ├── 10.五种通知.mp4│   │   ├── 11.Java代码配置AOP.mp4│   │   ├── 12.SpringAOP底层代理.mp4│   │   └── 13.通过注解定义AOP拦截规则.mp4│   ├── 03.JdbcTemplate│   │   ├── 01.JdbcTemplate基本操作.mp4│   │   ├── 02.增删改查.mp4│   │   └── 03.通过变量名传递参数.mp4│   └── 04.事务│       ├── 01.事务简介.mp4│       ├── 02.编程式事务.mp4│       ├── 03.XML配置声明式事务.mp4│       ├── 04.Java配置声明式事务.mp4│       ├── 05.Java+XML配置声明式事务.mp4│       ├── 06.自定义事务注解.mp4│       ├── 07.事务属性-隔离级别.mp4│       ├── 08.事务属性-传播性.mp4│       ├── 09.事务属性-传播性2.mp4│       ├── 10.事务属性-回滚规则.mp4│       ├── 11.事务属性-只读事务.mp4│       ├── 12.事务属性-超时时间.mp4│       └── 13.事务失效的场景.mp4└── 02.进阶用法    ├── 001.通过name属性定义别名.mp4    ├── 002.通过alias标签定义别名.mp4    ├── 003.别名处理接口AliasRegistry.mp4    ├── 004.aliasMap变量.mp4    ├── 005.allowAliasOverriding.mp4    ├── 006.hasAlias.mp4    ├── 007.removeAlias和isAlias.mp4    ├── 008.getAliases.mp4    ├── 009.checkForAliasCircle.mp4    ├── 010.canonicalName.mp4    ├── 011.registerAlias.mp4    ├── 012.resolveAliases.mp4    ├── 013.name属性解析原理.mp4    ├── 014.alias标签解析.mp4    ├── 015.DefaultListableBeanFactory.mp4    ├── 016.StaticListableBeanFactory.mp4    ├── 017.SimpleJndiBeanFactory.mp4    ├── 018.ApplicationContext.mp4    ├── 019.FactoryBean&SmartFactoryBean.mp4    ├── 020.FactoryBean处理思路.mp4    ├── 021.Bean提前加载流程分析.mp4    ├── 022.isFactoryBean方法分析.mp4    ├── 023.getBean中&的处理逻辑.mp4    ├── 024.BeanDefinition简介.mp4    ├── 025.RootBeanDefinition.mp4    ├── 026.ChildBeanDefinition.mp4    ├── 027.GenericBeanDefinition.mp4    ├── 028.AnnotatedGenericBeanDefinition.mp4    ├── 029.ScannedGenericBeanDefinition.mp4    ├── 030.ConfigurationClassBeanDefinition.mp4    ├── 031.CreateFromClassBeanDefinition.mp4    ├── 032.ClassDerivedBeanDefinition.mp4    ├── 033.加载XML配置的两种方式.mp4    ├── 034.BeanDefinitionReader.mp4    ├── 035.PropertiesBeanDefinitionReader.mp4    ├── 036.XmlBeanDefinitionReader.mp4    ├── 037.配置类解析为BeanDefinition.mp4    ├── 038.@Scope注解高级用法.mp4    ├── 039.编程式AOP.mp4    ├── 040.编程式AOP之target方法分析.mp4    ├── 041.TargetSource体系结构.mp4    ├── 042.SimpleBeanTargetSource.mp4    ├── 043.自定义TargetSource.mp4    ├── 044.引介增强.mp4    ├── 045.启动类上的@Scope注解代理原理.mp4    ├── 046.常规类上的@Scope注解.mp4    ├── 047.Java配置中的@Scope代理.mp4    ├── 048.导入配置类上的@Scope注解.mp4    ├── 049.@Configuration注解存在的意义是什么.mp4    ├── 050.@Configuration-Vs-@Component.mp4    ├── 051.@Configuration原理分析.mp4    ├── 052.@Configuration的两种模式Full和Lite.mp4    ├── 053.详细演示Full和Lite模式.mp4    ├── 054.Full模式和Lite模式特点总结.mp4    ├── 055.@Configuration注解解析源码分析.mp4    ├── 056.@Configuration注解解析源码分析-2.mp4    ├── 057.条件注解高级用法.mp4    ├── 058.条件注解高级用法补充.mp4    ├── 059.条件注解原理分析.mp4    ├── 060.beanName自动生成场景.mp4    ├── 061.beanName生成器分析.mp4    ├── 062.AnnotationBeanNameGenerator.mp4    ├── 063.BeanFactoryPostProcessor和BeanPostProcessor.mp4    ├── 064.BeanFactoryPostProcessor案例.mp4    ├── 065.BeanFactoryPostProcessor典型应用场景.mp4    ├── 066.Properties加载原理分析.mp4    ├── 067.BeanDefinitionRegistryPostProcessor.mp4    ├── 068.BeanFactoryPostProcessor作用时机分析.mp4    ├── 069.BeanPostProcessor接口分析.mp4    ├── 070.BeanPostProcessor实践.mp4    ├── 071.BeanPostProcessor实现AOP.mp4    ├── 072.MergedBeanDefinitionPostProcessor.mp4    ├── 073.BeanPostProcessor原理分析.mp4    ├── 074.合并BeanDefinition原理分析.mp4    ├── 075.合并BeanDefinition源码分析.mp4    ├── 076.父子容器原理分析.mp4    ├── 077.事件基本用法.mp4    ├── 078.事件是阻塞还是非阻塞.mp4    ├── 079.手动注册事件监听器.mp4    ├── 080.事件三大组件.mp4    ├── 081.Java类定义的事件监听器.mp4    ├── 082.Java类定义的事件监听器-补充.mp4    ├── 083.通过Java注解定义的事件监听器.mp4    ├── 084.ApplicationEventPublisher.mp4    ├── 085.ApplicationEventMulticaster.mp4    ├── 086.Spring事件补充.mp4    ├── 087.Java国际化.mp4    ├── 088.Spring国际化.mp4    ├── 089.MessageSource层级关系.mp4    ├── 090.getMessage方法原理分析.mp4    ├── 091.解析无参的key.mp4    ├── 092.解析有参key.mp4    ├── 093.Lifecycle基本用法.mp4    ├── 094.SmartLifecycle基本用法.mp4    ├── 095.Lifecycle中start方法执行原理.mp4    ├── 096.Lifecycle中stop方法执行原理.mp4    ├── 097.编程式AOP.mp4    ├── 098.动态代理对象创建流程.mp4    ├── 099.JDK和CGLIB动态代理分析.mp4    ├── 100.Advisor详解.mp4    ├── 101.自定义切面对象Advisor.mp4    ├── 102.重载方法拦截规则.mp4    ├── 103.拦截所有方法.mp4    ├── 104.默认配置的Pointcut对象.mp4    ├── 105.Pointcut经典写法.mp4    ├── 106.Pointcut分类.mp4    ├── 107.StaticMethodMatcherPointcut.mp4    ├── 108.StaticMethodMatcherPointcut-2.mp4    ├── 109.DynamicMethodMatcherPointcut.mp4    ├── 110.AnnotationMatchingPointcut.mp4    ├── 111.ControlFlowPointcut.mp4    ├── 112.ComposablePointcut.mp4    ├── 113.提前返回Bean的机会.mp4    ├── 114.提前AOP的机会.mp4    ├── 115.理解两个关键变量.mp4    ├── 116.特殊的beanName.mp4    ├── 117.自定义TargetSourceCreator.mp4    ├── 118.提前AOP实践.mp4    ├── 119.AOP创建的契机.mp4    ├── 120.AOP对象生成整体思路.mp4    ├── 121.AOP对象创建详细流程分析.mp4    ├── 122.Bean的获取思路.mp4    ├── 123.getBean方法整体思路分析.mp4    ├── 124.从三级缓存中加载Bean.mp4    ├── 125.从parent中加载Bean.mp4    ├── 126.检查@DependOn注解.mp4    ├── 127.不同Scope获取Bean实例.mp4    ├── 128.生成的Bean类型检查.mp4    ├── 129.createBean方法分析.mp4    ├── 130.doCreateBean-1.mp4    ├── 131.循环依赖-二级缓存.mp4    ├── 132.循环依赖-三级缓存.mp4    ├── 133.循环依赖-三级缓存-补充.mp4    ├── 134.循环依赖源码分析-1.mp4    ├── 135.循环依赖源码分析-2.mp4    ├── 136.循环依赖源码分析-3.mp4    ├── 137.Bean的生命周期-1.mp4    ├── 138.Bean的生命周期-2.mp4    ├── 139.Bean的生命周期-3.mp4    ├── 140.Bean的实例化-1.mp4    ├── 141.Bean的实例化-2.mp4    ├── 142.Bean的属性注入.mp4    ├── 143.getBean方法.mp4    └── 144.小结.mp4

DLG28资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-26-91533-0.htmlSpring 中如何控制 Bean 的加载顺序?

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: 开 1000 个 Web Worker!我的页面能起飞吗?

下一篇: 用Rust和OpenCV打造ASCII图片

标签:
  • 热门焦点
  • 官方承诺:K60至尊版将会首批升级MIUI 15

    官方承诺:K60至尊版将会首批升级MIUI 15

    全新的MIUI 15今天也有了消息,在官宣了K60至尊版将会搭载天玑9200+处理器和独显芯片X7的同时,Redmi给出了官方承诺,K60至尊重大更新首批升级,会首批推送MIUI 15。也就是说虽然
  • .NET 程序的 GDI 句柄泄露的再反思

    .NET 程序的 GDI 句柄泄露的再反思

    一、背景1. 讲故事上个月我写过一篇 如何洞察 C# 程序的 GDI 句柄泄露 文章,当时用的是 GDIView + WinDbg 把问题搞定,前者用来定位泄露资源,后者用来定位泄露代码,后面有朋友反
  • 虚拟键盘 API 的妙用

    虚拟键盘 API 的妙用

    你是否在遇到过这样的问题:移动设备上有一个固定元素,当激活虚拟键盘时,该元素被隐藏在了键盘下方?多年来,这一直是 Web 上的默认行为,在本文中,我们将探讨这个问题、为什么会发生
  • Temu起诉SHEIN,跨境电商战事升级

    Temu起诉SHEIN,跨境电商战事升级

    来源 | 伯虎财经(bohuFN)作者 | 陈平安日前据外媒报道,拼多多旗下跨境电商平台Temu正对竞争对手SHEIN提起新诉讼,诉状称Shein“利用市场支配力量强迫服装厂商与之签订独家
  • 电视息屏休眠仍有网络上传 爱奇艺被质疑“薅消费者羊毛”

    电视息屏休眠仍有网络上传 爱奇艺被质疑“薅消费者羊毛”

    记者丨宁晓敏 见习生丨汗青出品丨鳌头财经(theSankei) 前不久,爱奇艺发布了一份亮眼的一季报,不仅营收和会员营收创造历史最佳表现,其运营利润也连续6个月实现增长。自去年年初
  • 得物宠物生意「狂飙」,发力“它经济”

    得物宠物生意「狂飙」,发力“它经济”

    作者|花花小萌主近日,得物宣布正式上线宠物鉴别,通过得物App内的“在线鉴别”,可找到鉴别宠物的选项。通过上传自家宠物的部位细节,就能收获拥有专业资质认证的得物鉴
  • “又被陈思诚骗了”

    “又被陈思诚骗了”

    作者|张思齐 出品|众面(ID:ZhongMian_ZM)如今的国产悬疑电影,成了陈思诚的天下。最近大爆电影《消失的她》票房突破30亿断层夺魁暑期档,陈思诚再度风头无两。你可以说陈思诚的
  • iQOO 11S屏幕细节公布:首发三星2K E6全感屏 安卓最好的直屏手机

    iQOO 11S屏幕细节公布:首发三星2K E6全感屏 安卓最好的直屏手机

    日前iQOO手机官方宣布,新一代电竞旗舰iQOO 11S将会在7月4日19:00正式与大家见面。随着发布时间的日益临近,官方关于该机的预热也更加密集,截至目前已
  • 到手价3099元起!iQOO Neo8 Pro今日首销:安卓性能最强旗舰

    到手价3099元起!iQOO Neo8 Pro今日首销:安卓性能最强旗舰

    5月23日,iQOO如期举行了新品发布会,全新的iQOO Neo8系列也正式与大家见面,包含iQOO Neo8和iQOO Neo8 Pro两个版本,其中标准版搭载高通骁龙8+,而Pro版更
Top