您当前的位置:首页 > 电脑百科 > 程序开发 > 框架

如何正确控制springboot中bean的加载顺序总结

时间:2020-07-16 15:56:10  来源:  作者:

1.为什么需要控制加载顺序

springboot遵从约定大于配置的原则,极大程度的解决了配置繁琐的问题。在此基础上,又提供了spi机制,用spring.factories可以完成一个小组件的自动装配功能。

在一般业务场景,可能你不大关心一个bean是如何被注册进spring容器的。只需要把需要注册进容器的bean声明为@Component即可,spring会自动扫描到这个Bean完成初始化并加载到spring上下文容器。

而当你在项目启动时需要提前做一个业务的初始化工作时,或者你正在开发某个中间件需要完成自动装配时。你会声明自己的Configuration类,但是可能你面对的是好几个有互相依赖的Bean。如果不加以控制,这时候可能会报找不到依赖的错误。

但是你明明已经把相关的Bean都注册进spring上下文了呀。这时候你需要通过一些手段来控制springboot中的bean加载顺序。

2.几个误区

在正式说如何控制加载顺序之前,先说2个误区。

在标注了@Configuration的类中,写在前面的@Bean一定会被先注册

这个不存在的,spring在以前xml的时代,也不存在写在前面一定会被先加载的逻辑。因为xml不是渐进的加载,而是全部parse好,再进行依赖分析和注册。到了springboot中,只是省去了xml被parse成spring内部对象的这一过程,但是加载方式并没有大的改变。

利用@Order这个标注能进行加载顺序的控制

严格的说,不是所有的Bean都可以通过@Order这个标注进行顺序的控制。你把@Order这个标注加在普通的方法上或者类上一点鸟用都没有。

那@Order能控制哪些bean的加载顺序呢,我们先看看官方的解释:

如何正确控制springboot中bean的加载顺序总结

 

最开始@Order注解用于切面的优先级指定;在 4.0 之后对它的功能进行了增强,支持集合的注入时,指定集合中 bean 的顺序,并且特别指出了,它对于当 实例的 bean 之间的顺序,没有任何影响。

目前用的比较多的有以下3点:

  • 控制AOP的类的加载顺序,也就是被@Aspect标注的类
  • 控制ApplicationListener实现类的加载顺序
  • 控制CommandLineRunner实现类的加载顺序

3.如何控制

3.1@DependsOn

@DependsOn注解可以用来控制bean的创建顺序,该注解用于声明当前bean依赖于另外一个bean。所依赖的bean会被容器确保在当前bean实例化之前被实例化。

示例:

如何正确控制springboot中bean的加载顺序总结

 

以上代码bean的加载顺序为:

如何正确控制springboot中bean的加载顺序总结

 

@DependsOn的使用:

直接或者间接标注在带有@Component注解的类上面;

直接或者间接标注在带有@Bean注解的方法上面;

使用@DependsOn注解到类层面仅仅在使用 component-scanning 方式时才有效,如果带有@DependsOn注解的类通过XML方式使用,该注解会被忽略,<bean depends-on="..."/>这种方式会生效。

3.2 参数注入

在@Bean标注的方法上,如果你传入了参数,springboot会自动会为这个参数在spring上下文里寻找这个类型的引用。并先初始化这个类的实例。

利用此特性,我们也可以控制bean的加载顺序。

示例:

如何正确控制springboot中bean的加载顺序总结

 

以上结果,beanB先于beanA被初始化加载。

需要注意的是,springboot会按类型去寻找。如果这个类型有多个实例被注册到spring上下文,那你就需要加上@Qualifier("Bean的名称")来指定

3.3 利用bean的生命周期中的扩展点

在spring体系中,从容器到Bean实例化&初始化都是有生命周期的,并且提供了很多的扩展点,允许你在这些步骤时进行逻辑的扩展。

这些可扩展点的加载顺序由spring自己控制,大多数是无法进行干预的。我们可以利用这一点,扩展spring的扩展点。在相应的扩展点加入自己的业务初始化代码。从来达到顺序的控制。

3.4 @AutoConfigureOrder

这个注解用来指定配置文件的加载顺序。但是在实际测试中发现,以下这样使用是不生效的:

如何正确控制springboot中bean的加载顺序总结

 

无论你2个数字填多少,都不会改变其加载顺序结果。

那这个@AutoConfigureOrder到底是如何使用的呢。

经过测试发现,@AutoConfigureOrder只能改变外部依赖的@Configuration的顺序。如何理解是外部依赖呢。

能被你工程内部scan到的包,都是内部的Configuration,而spring引入外部的Configuration,都是通过spring特有的spi文件:spring.factories

换句话说,@AutoConfigureOrder能改变spring.factories中的@Configuration的顺序。

具体使用方式:

如何正确控制springboot中bean的加载顺序总结

 

spring.factories:

如何正确控制springboot中bean的加载顺序总结

 

4.总结

其实在工作中,我相信很多人碰到过复杂的依赖关系的bean加载,把这种不确定性交给spring去做,还不如我们自己去控制,这样在阅读代码的时候 ,也能轻易看出bean之间的依赖先后顺序。



Tags:springboot bean   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
1.为什么需要控制加载顺序springboot遵从约定大于配置的原则,极大程度的解决了配置繁琐的问题。在此基础上,又提供了spi机制,用spring.factories可以完成一个小组件的自动装配...【详细内容】
2020-07-16  Tags: springboot bean  点击:(163)  评论:(0)  加入收藏
▌简易百科推荐
近日只是为了想尽办法为 Flask 实现 Swagger UI 文档功能,基本上要让 Flask 配合 Flasgger, 所以写了篇 Flask 应用集成 Swagger UI 。然而不断的 Google 过程中偶然间发现了...【详细内容】
2021-12-23  Python阿杰    Tags:FastAPI   点击:(6)  评论:(0)  加入收藏
文章目录1、Quartz1.1 引入依赖<dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz</artifactId> <version>2.3.2</version></dependency>...【详细内容】
2021-12-22  java老人头    Tags:框架   点击:(11)  评论:(0)  加入收藏
今天来梳理下 Spring 的整体脉络啦,为后面的文章做个铺垫~后面几篇文章应该会讲讲这些内容啦 Spring AOP 插件 (了好久都忘了 ) 分享下 4ye 在项目中利用 AOP + MybatisPlus 对...【详细内容】
2021-12-07  Java4ye    Tags:Spring   点击:(14)  评论:(0)  加入收藏
&emsp;前面通过入门案例介绍,我们发现在SpringSecurity中如果我们没有使用自定义的登录界面,那么SpringSecurity会给我们提供一个系统登录界面。但真实项目中我们一般都会使用...【详细内容】
2021-12-06  波哥带你学Java    Tags:SpringSecurity   点击:(18)  评论:(0)  加入收藏
React 简介 React 基本使用<div id="test"></div><script type="text/javascript" src="../js/react.development.js"></script><script type="text/javascript" src="../js...【详细内容】
2021-11-30  清闲的帆船先生    Tags:框架   点击:(19)  评论:(0)  加入收藏
流水线(Pipeline)是把一个重复的过程分解为若干个子过程,使每个子过程与其他子过程并行进行的技术。本文主要介绍了诞生于云原生时代的流水线框架 Argo。 什么是流水线?在计算机...【详细内容】
2021-11-30  叼着猫的鱼    Tags:框架   点击:(21)  评论:(0)  加入收藏
TKinterThinter 是标准的python包,你可以在linx,macos,windows上使用它,你不需要安装它,因为它是python自带的扩展包。 它采用TCL的控制接口,你可以非常方便地写出图形界面,如...【详细内容】
2021-11-30    梦回故里归来  Tags:框架   点击:(26)  评论:(0)  加入收藏
前言项目中的配置文件会有密码的存在,例如数据库的密码、邮箱的密码、FTP的密码等。配置的密码以明文的方式暴露,并不是一种安全的方式,特别是大型项目的生产环境中,因为配置文...【详细内容】
2021-11-17  充满元气的java爱好者  博客园  Tags:SpringBoot   点击:(25)  评论:(0)  加入收藏
一、搭建环境1、创建数据库表和表结构create table account(id INT identity(1,1) primary key,name varchar(20),[money] DECIMAL2、创建maven的工程SSM,在pom.xml文件引入...【详细内容】
2021-11-11  AT小白在线中  搜狐号  Tags:开发框架   点击:(29)  评论:(0)  加入收藏
SpringBoot开发的物联网通信平台系统项目功能模块 功能 说明 MQTT 1.SSL支持 2.集群化部署时暂不支持retain&will类型消 UDP ...【详细内容】
2021-11-05  小程序建站    Tags:SpringBoot   点击:(55)  评论:(0)  加入收藏
最新更新
栏目热门
栏目头条