【Spring】IOC/DI中常用的注解@Order与@DependsOn

目录

1、@Order 注解改变Bean自动注入的顺序

1.1、了解@SpringBootTest注解

1.2、@Order 注解改变Bean自动注入的顺序

2、@DependsOn 改变Bean的创建顺序

1、@Order 注解改变Bean自动注入的顺序

        在sping中,通过IOC(控制反转)和DI(依赖注入)这种机制,可以将对象的依赖注入到该对象中,而不是在对象内部直接创建依赖。以达到降低耦合度,提高代码的可维护性和灵活性的目的。

1.1、了解@SpringBootTest注解

@SpringBootTest(classes = 配置类名称.class)

基本等同于启动了整个服务,此时便可以开始功能测试。

        当@SpringBootTest没有指定配置类的时候,默认是把@SpringBootApplication注解下的类作为配置类,然后就会去扫描这个默认配置类所在的包,原因如下图所示

        这里例子里@SpringBootApplication注解下的类所在包为:com.lt,要扫描这个包,把这个包下配置的bean加载到spring容器中去,这些bean才会生效。

(1)如果注解@SpringBootTest(classes = 配置类名称.class)中指定了默认项目配置类,则该测试类可以放在test.java下任何包中,比如:

        图中的测试类(C3IocApplicationTests)的注解@SpringBootTest指定了C3IocApplication(默认项目配置类)为配置类,这时候测试类(C3IocApplicationTests)就可以放在test.java下任何包中

(2)如果注解@SpringBootTest没有配置里面的参数classes = C3IocApplication(默认项目配置类),则需要确保test.java下的测试类所在的包与默认项目配置类所在的包一致,即在test.java下也需要创建com.lt包,并将测试类放在该包下,比如:

        图中的测试类(C3IocApplicationTests)的注解@SpringBootTest没有配置里面的参数classes = C3IocApplication(默认项目配置类),所以这里test.java下的测试类(C3IocApplicationTests)必须与默认配置类(C3IocApplication)所在的包(com.lt)一致,都是在com.lt这个包下

1.2、@Order 注解改变Bean自动注入的顺序

        注解@Order或者接口Ordered的作用是定义Spring IOC容器中Bean的执行顺序的优先级,而不是定义Bean的加载顺序,Bean的加载顺序不受@Order或Ordered接口的影响。所以这里说改变Bean的自动注入的顺序就是改变Bean的执行顺序。

相关代码

//接口
public interface I {
}//接口I的实现类A
public class A implements I{public A(){System.out.println("A");}
}//接口I的实现类A
public class B implements I{public B(){System.out.println("B");}
}//测试类TestOrder
//@SpringBootTest(classes = 启动类名称.class),这里配置了TestOrder.class为项目启动类
@SpringBootTest(classes = TestOrder.class)
public class TestOrder {@Beanpublic A a(){return new A();}@Beanpublic B b(){return new B();}@Testpublic void test(@Autowired List<I> i){//这里不用List集合的话就只能获取一个I的bean,//但是I是有两个实现类的bean,这时候它不知道注入哪一个,就会报错,//使用了List集合的话,就会把I的两个实现类的bean都注入到List集合中System.out.println(i);//没有使用@Order注解时的打印结果为:[com.lt.order.A@4760f169, com.lt.order.B@261ea657]//这时候是A在前面,B在后面}}

        在测试类中,用@Autowired注入 I 的bean时,如果不用List集合的话就只能获取一个 I 的bean,但是 I 是有两个实现类的bean,这时候它不知道注入哪一个,就会报错,使用了List集合的话,就会把 I 的两个实现类的bean都注入到List集合中,并且这些bean在List集合中是有顺序的,如果这时候我们想哪个bean排在前面(先执行),就可以通过@Order去改变他的自动装配顺序,谁@Order里面的值小谁排在前面

示例:

用法一,直接加注解,@Order注解中的属性值越小就排的越前

@SpringBootTest(classes = TestOrder.class)
public class TestOrder {@Bean@Order(1)public A a(){return new A();}@Bean@Order(0) // 谁小谁在前面public B b(){return new B();}@Testpublic void test(@Autowired List<I> i){System.out.println(i);//使用@Order注解后的打印结果为:[com.lt.order.B@261ea657, com.lt.order.A@4760f169]//这时候变成了B在前面,A在后面}
}

用法二,实现Ordered接口,重写接口中的getOrder()方法,这个方法的返回值越小,实现类作为bean在List数组中就排的越前面。这下面代码的结果和上面直接加注解的结果一样

public class A implements I, Ordered {public A(){System.out.println("A");}@Overridepublic int getOrder() {return 1;}
}public class B implements I, Ordered {public B(){System.out.println("B");}@Overridepublic int getOrder() {return 0;}
}

2、@DependsOn 改变Bean的创建顺序

        @DependsOn注解可以定义在类和方法上,意思是我这个组件要依赖于另一个组件,也就是说被依赖的组件会比该组件先注册到IOC容器中。

使用场景:

        比如我现在有A类和B类,A类是数据库查询,B类是数据库连接,在javaconfig(配置类)中使用@Bean注解把这两个类配置成bean时,可以通过把B类配置成bean的语句写在A类配置成bean的语句前面,来实现先连接数据再查询数据库,但如果配置bean的方式用的是@Component及其衍生注解时,就不好控制bean的创建顺序了,这时候就可以用@DependsOn来改变Bean的创建顺序。

        需要用到观察者模式的情况下通常都需要用到该注解,观察者模式(详细可查看相关文章)有三要输,观察者、事件源、事件,机制是观察者会监听数据源的某些时间,当事件源触发该事件后,观察者就会知道进行相应措施。

        比如老师是观察者,学生是事件源,学生迟到是事件,老师观察学生是否迟到,每当学生迟到,老师就会发现,并处罚该学生。

        这类场景一般需要观察者要比事件源先创建,才能不遗漏事件源触发的每一个事件,要是事件源先创建,可能会在观察者创建前就触发了事件而观察者无法知道。

        比如上述例子,八点算迟到,但是老师自己都八点半才到学校,所以就无法知道八点到八点半之间迟到的学生。

@DependsOn注解可以作用在方法和类上。

(1)当@DependsOn注解作用在类上时

当作用在类上时,通常会与@Component及其衍生注解等注解配合使用。

示例:

代码:还没使用@DependsOn注解

//事件源EventSource,在com.lt.dependsOn包下
@Component
public class EventSource {public EventSource(){//当调用这个无参构造函数创造bean时,就会执行这条打印语句System.out.println("事件源创建");}
}//监听类EventTListener,在com.lt.dependsOn包下
@Component
public class EventTListener {public EventTListener(){//当调用这个无参构造函数创造bean时,就会执行这条打印语句System.out.println("监听器创建");}
}//测试类TestDepends,在com.lt.dependsOn包下
@ComponentScan("com.lt.dependsOn")  //这里要指定扫描"com.lt.dependsOn"这个包,因为这时候用的是@Component来配置bean
@SpringBootTest(classes = TestDepends.class)
public class TestDepends {@Testpublic void test(){}
}

还没使用@DependsOn注解的运行结果

因为spring默认扫描包时会根据文件在文件夹的位置先后顺序扫描加载,而EventSource 文件位置在EventTListener前面,所以会先加载EventSource 事件源组件。但这就使得两个类的依赖关系不符合逻辑。

使用@DependsOn注解:

//事件源
@Component
@DependsOn(value = {"eventTListener"})
public class EventSource {public EventSource(){//当调用这个无参构造函数创造bean时,就会执行这条打印语句System.out.println("事件源创建");}
}

使用@DependsOn注解的运行结果:

这时候就是监听器先创建了。注意:@DependsOn中value属性的bean id必须存在,不然会报错。

(2)当@DependsOn注解作用在方法上时

当作用在方法上时,通常会与@Bean注解配合使用。

要把EventSource和EventTListener类上的注解去掉,再使用下面的代码,因为下面是使用@Bean注解来配置bean的方式

测试类TestDepends代码:

//测试类
@SpringBootTest(classes = TestDepends.class)
public class TestDepends {@Bean@DependsOn(value = {"eventListener"})public EventSource eventSource(){return new EventSource();}@Beanpublic EventTListener eventListener(){return new EventTListener();}@Testpublic void test(){}
}

如果不加@DependsOn注解的话,就会先创建事件源,如果加了(如上代码),就会先创建监听器(如下图)

推荐: 
【Spring】依赖注入(DI)时常用的注解@Autowired和@Value-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/m0_65277261/article/details/137784706?spm=1001.2014.3001.5501

【Java网络编程】TCP通信(Socket 与 ServerSocket)和UDP通信的三种数据传输方式-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/m0_65277261/article/details/137926277?spm=1001.2014.3001.5501【Spring】使用@Bean和@Import注解配置Bean,与Bean的实例化_import和bean-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/m0_65277261/article/details/137257177?spm=1001.2014.3001.5501

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

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

相关文章

文本向量化模型新突破——acge_text_embedding勇夺C-MTEB榜首

在人工智能的浪潮中&#xff0c;以GPT4、Claude3、Llama 3等大型语言模型&#xff08;LLM&#xff09;无疑是最引人注目的潮头。这些模型通过在海量数据上的预训练&#xff0c;学习到了丰富的语言知识和模式&#xff0c;展现了出惊人的能力。在支撑这些大型语言模型应用落地方面…

文件操作(1)

为什么使⽤⽂件&#xff1f; 如果没有⽂件&#xff0c;我们写的程序的数据是存储在电脑的内存中&#xff0c;如果程序退出&#xff0c;内存回收&#xff0c;数据就丢失了&#xff0c;等再次运⾏程序&#xff0c;是看不到上次程序的数据的&#xff0c;如果要将数据进⾏持久化的…

各平台奇怪问题备忘录

微信小程序 小程序报错Page 页面路径 has not been register yet 描述&#xff1a;uniapp做微信小程序开发时&#xff0c;新增某页面后&#xff0c;小程序跳转该页面报错Page 页面路径 has not been register yet 已知&#xff1a;page.json已添加该页面&#xff0c;小程序a…

B端设计实战:基于角色属性的权限设计

编辑导读:“权限控制”是中后台的基础能力,用于管控操作人员在平台内可做的事项内容。即通过权限控制,可以决定哪些人在平台内可以做哪些事。本文作者围绕角色&属性的权限设计展开分析,希望对你有帮助。 Hello,我是一名交互设计师。 随着3月暖春的即将到来,苏州的疫…

bugku-杂项-社工进阶收集

下载附件 得到图片 利用百度地图查找 这里得到地点名称大雁塔音乐喷泉 陕西省西安市&#xff0c;大雁塔北广场 打开高德地图 来到大雁塔北广场 因为在北广场&#xff0c;所以地铁站为大雁塔站 开始分析 坐七站到大雁塔站&#xff0c;即始发站为韦曲南站 因为始发站离她家800米&…

高频前端面试题汇总之HTML篇

1. src和href的区别 src和href都是用来引用外部的资源&#xff0c;它们的区别如下&#xff1a; src&#xff1a; 表示对资源的引用&#xff0c;它指向的内容会嵌入到当前标签所在的位置。src会将其指向的资源下载并应⽤到⽂档内&#xff0c;如请求js脚本。当浏览器解析到该元素…

34. BI - 美国大学生足球队的 GCN 案例

本文为 「茶桁的 AI 秘籍 - BI 篇 第 34 篇」 文章目录 美国大学生足球队 Embedding&#xff08;GCN&#xff09; Hi&#xff0c;你好。我是茶桁。 在上一节课中&#xff0c;因为需要&#xff0c;我们先是回顾了一下 Graph Embedding&#xff0c;然后跟大家讲解了 GCN 以及其算…

linux驱动-CCF-0基础

1. 时钟设备 晶振&#xff1a;提供基础时钟源的&#xff08;可分为有源晶振、无源晶振两种&#xff09;&#xff1b; PLL: 用于倍频的锁相环&#xff1b; mux: 用于多路时钟源选择&#xff1b; Divider: 用于分频的&#xff1b; gate: 用于时钟使能的与门电路等 2. CCF…

Python读写文本URL蓝牙WIFI自动连接电子名片位置坐标智能海报等NDEF标签

本示例使用的发卡器&#xff1a;https://item.taobao.com/item.htm?id615391857885&spma1z10.5-c.w4002-21818769070.11.60ad789erlonvk 近场通信&#xff08;Near Field Communication&#xff0c;简称NFC&#xff09;&#xff0c;是一种新兴的技术&…

技术速递|Java on Azure Tooling 3月更新 - Java on Azure 开发工具未来六个月路线图发布

作者&#xff1a;Jialuo Gan - Program Manager, Developer Division At Microsoft 排版&#xff1a;Alan Wang 大家好&#xff0c;欢迎阅读 Java on Azure 工具的三月更新。在本次更新中&#xff0c;我们将分享未来几个月对 Java on Azure 开发工具的投资。此外&#xff0c;我…

Redis入门到通关之数据结构解析-Dict

文章目录 概述构成Dict的扩容Dict的rehash总结 欢迎来到 请回答1024 的博客 &#x1f353;&#x1f353;&#x1f353;欢迎来到 请回答1024的博客 关于博主&#xff1a; 我是 请回答1024&#xff0c;一个追求数学与计算的边界、时间与空间的平衡&#xff0c;0与1的延伸的后端开…

SpringBoot引入第三方jar包或本地jar包

idea2018创建spring boot项目 New Project窗口选择Spring Initializr Type选择Maven(Generate…),有两个Maven选择这一个。 勾选Spring Web。 pom.xml中version改成2.5.10。 在resources中新建jar目录&#xff0c;将第三方jar包fastjson2-2.0.47.jar放入其中。&#xff08…

国产FTP文件传输服务器需要具备哪些关键特性?

国产FTP文件传输服务器是指根据中国国内信息技术创新&#xff08;信创&#xff09;的要求和标准&#xff0c;自主研发的文件传输服务器软件。这类软件旨在替代传统的FTP服务器&#xff0c;以更好地适应国产化和信息安全的需要。国产FTP文件传输服务器通常需要具备以下要求&…

【ensp】网关冗余vrrp实验

基础文字知识复习时&#xff0c;添加&#xff0c;下文仅拓扑以及核心配置以及结果分析 冗余路由器 核心代码&#xff1a; int g0/0/0 [R1-GigabitEthernet0/0/0]vrrp vrid 1 virtual-ip 192.168.10.1 ###设置虚拟ip [R1-GigabitEthernet0/0/0]vrrp vrid 1 priority 120 …

零碳家庭 “光”的力量

有行业专家乐观预测&#xff0c;在供给充足、基础设施建设与时俱进的情况下&#xff0c;2025年&#xff0c;我国新能源汽车市场的占有率将会达到50%&#xff0c;2030年更有望突破90%的大关。为了方便新能源汽车的出行&#xff0c;在家中安装一个智能充电桩是越来越多驾驶者的选…

分类预测 | Matlab实现RIME-BP霜冰优化BP神经网络多特征分类预测

分类预测 | Matlab实现RIME-BP霜冰优化BP神经网络多特征分类预测 目录 分类预测 | Matlab实现RIME-BP霜冰优化BP神经网络多特征分类预测分类效果基本介绍程序设计参考资料 分类效果 基本介绍 1.RIME-BP霜冰优化BP神经网络多特征分类预测&#xff08;Matlab实现完整源码和数据&a…

免杀技术之白加黑的攻击防御

一、介绍 1. 什么是白加黑 通俗的讲白加黑中的白就是指被杀软列入到可信任列表中的文件。比如说微软自带的系统文件或者一些有有效证书签名的文件,什么是微软文件&#xff0c;或者什么是有效签名文件在后面我们会提到他的辨别方法。黑就是指我们自己的文件&#xff0c;没有有…

【MCU】栈溢出问题

项目场景&#xff1a; 硬件&#xff1a;STM32F407&#xff0c;操作系统&#xff1a;rt_thread master分支 问题描述 问题栈溢出 id 499 ide 00 rtr 00 len 8 9 Function[rt_completion_wait] shall not be used in ISR (0) assertion failed at function:rt_completion_wait,…

屏幕状态自动检测+鼠标自动操作

目录 一、写在前面 1.1适用场景 1.2涉及到的库 二、函数库 2.1pyautogui-屏幕截图&鼠标操作 2.1.1屏幕截图screenshot函数 2.1.2鼠标移动及单击 2.2Opencv-模板匹配 2.2.1matchTemplate函数 2.2.2minMaxLoc函数 2.2.3相关代码 2.3base64-图片转base64 2.3.1在线…

Spring MVC和Spring Boot

上节已经提到过请求&#xff0c;这次梳理响应。 响应 响应基本上都要被Controller所托管&#xff0c;告诉Spring帮我们管理这个代码&#xff0c;我们在后面需要访问时&#xff0c;才可以进行访问&#xff0c;否则将会报错。并且其是由RestController分离出来的&#xff0c;Re…