用户名
Email
论坛
潜水/灌水快乐,沉淀知识,认识更多同行。
ToB圈子
加入IT圈,遇到更多同好之人。
朋友圈
看朋友圈动态,了解ToB世界。
ToB门户
了解全球最新的ToB事件
博客
Blog
排行榜
Ranklist
文库
业界最专业的IT文库,上传资料也可以赚钱
下载
分享
Share
导读
Guide
相册
Album
记录
Doing
应用中心
帖子
本版
文章
帖子
ToB圈子
用户
免费入驻
产品入驻
解决方案入驻
公司入驻
案例入驻
登录
·
注册
只需一步,快速开始
账号登录
立即注册
找回密码
用户名
自动登录
找回密码
密码
登录
立即注册
首页
找靠谱产品
找解决方案
找靠谱公司
找案例
找对的人
专家智库
悬赏任务
圈子
SAAS
IT评测·应用市场-qidao123.com技术社区
»
论坛
›
软件与程序人生
›
程序人生
›
@PostConstruct、@DependsOn、@Order注解嵌套使用办理Be ...
@PostConstruct、@DependsOn、@Order注解嵌套使用办理Bean加载优先级问题 ...
笑看天下无敌手
论坛元老
|
2024-9-20 17:23:20
|
显示全部楼层
|
阅读模式
楼主
主题
1965
|
帖子
1965
|
积分
5895
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要
登录
才可以下载或查看,没有账号?
立即注册
x
踩坑:@PostConstruct、@DependsOn、@Order注解嵌套使用案例
本日在工作中写需求代码时,遇到的一个关于Sping Bean对象加载优先级问题,结合了Spring源码,大概总结了一下遇到Bean加载序次需求问题时,比较常用的3个注解:@PostConstruct、@DependsOn、@Order。
一、@Order注解的作用
@Order注解的作用是界说Spring IOC容器中Bean的实行序次的优先级。
使用案例:
@Component
@Order(0)
public class Test01 {
...
}
@Component
@Order(1)
public class Test02 {
...
}
@Component
@Order(2)
public class Test03 {
...
}
复制代码
如上述代码所示,通过@Order注解界说优先级,3个Bean对象从IOC容器中的加载序次为:
Test01、Test02、Test03
。
二、@PostConstruct注解的作用
@PostConstruct注解可以用于修饰一个非静态的、返回值类型为
void
的方法(eg:myInit())。
该方法(myInit())会在服务器加载Servlet的时间被实行,且只会被实行一次
!
该方法(myInit())的调用实行在构造函数之后,在Servlet的 init() 方法之前,在Servlet的 destroy()方法之后
。
使用案例:
@Component
public class Test {
@PostConstruct
private void init() {
// 初始化
System.out.println("World!");
}
public Test(){
System.out.println("Hello");
}
}
复制代码
输出效果:
Hello
World!
复制代码
三、@DependsOn注解的作用
该注解的作用顾名思义,就是 “谁依赖谁”。
如果在Test02类上加上@DependsOn(value = "test01"),那么就阐明Test02在加载时,要依赖于Test01,Spring IOC 容器会优先加载Test01,然后再加载Test02。
举个现实业务场景的案例,假设如今有2个类Test01、Test02,必要交给Spring IOC容器托管:
/**
* Test01是一个拥有1个静态变量的类
*/
@Component
public class Test01 {
// 该静态变量的属性值需要通过Spring容器赋值,值(hello)定义在application.properties中。
// 注意:@Value注解不可以给静态变量注入属性值 (否则获取的注入结果为null) !
// 因此HELLO的属性值注入要在setter方法上加上@Value注解,参考文章:【https://blog.csdn.net/weixin_43591980/article/details/121503720】
public static String HELLO;
public static String WORLD;
@Value("${spring.test.hello}")// 值为hello
public void setHELLO(String hello) {
HELLO = hello;
}
@Value("${spring.test.world}")// 值为world
public void setWORLD(String world) {
WORLD = easak;
}
}
复制代码
再来看Test02类的代码(
前提要求:Test02类必要在我们的Spring Boot项目启动时首先被初始化调用
!):
/**
* Test02拥有一个@PostConstruct注解修饰的init()初始化方法和无参构造函数
*/
@Component
public class Test02 {
@PostConstruct
public void init(){
...
}
public Test02(){
...
}
}
复制代码
业务需求:我必要在Test02的无参构造方法加载时,控制台打印Test01类中的HELLO静态变量值,然后在 init()方法实行时,控制台打印Test01类中的WORLD静态变量值。
刚开始我的第一想法是,直接这样写就好了:
@PostConstruct
public void init(){
System.out.println(Test01.HELLO);
}
public Test02(){
System.out.println(Test02.WORLD);
}
复制代码
但是终极控制台打印的效果为:
null
null
复制代码
Why?为什么是这个效果?
由于,
Test02类会在我们的Spring Boot项目启动时首先被初始化调用
,也就是说IOC容器会首先去加载Test02对象,而这时间Test01还尚未被加载到容器中,这时间Test01中的两个静态变量HELLO、WORLD还没有通过@Value注解注入属性值,所以效果理所应当是输出 null ~
办理方案:使用@DependsOn注解
我们对Test02类进行改进:
@Component
@DependsOn(value = "test01")// 通过该注解,向Spring容器声明,该类的加载需要依赖于Test01,当加载Test02时,要先去加载Test01!
public class Test02 {
@PostConstruct
public void init(){
System.out.println(Test01.HELLO);
}
public Test02(){
System.out.println(Test01.WORLD);
}
}
复制代码
查看打印效果:
hello
world
复制代码
注:也可以使用@Order注解给Test01、Test02类声明加载优先级,优先加载Test01,然后再加载Test02!
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复
举报
0 个回复
倒序浏览
返回列表
快速回复
高级模式
B
Color
Image
Link
Quote
Code
Smilies
您需要登录后才可以回帖
登录
or
立即注册
本版积分规则
发表回复
回帖并转播
回帖后跳转到最后一页
发新帖
回复
笑看天下无敌手
论坛元老
这个人很懒什么都没写!
楼主热帖
mysql精简单机版,免登录,可复制,不 ...
计算机视觉-OpenCV图像金字塔 ...
Java如何使用流式编程的方式访问url呢 ...
【毕业季】-职场10年大咖有话想说 ...
Gitee教程实战(企业级) 包含详细的出 ...
一个工作薄中快速新建多个数据表 ...
使用ansible部署服务到k8s
使用 Kubeadm 部署 Kubernetes(K8S) 安 ...
什么是真正的HTAP?(一)背景篇 ...
【牛客刷题-SQL进阶挑战】NO1.增删改操 ...
标签云
集成商
AI
运维
CIO
存储
服务器
浏览过的版块
Mysql
登录参与点评抽奖加入IT实名职场社区
下次自动登录
忘记密码?点此找回!
登陆
新用户注册
用其它账号登录:
关闭
快速回复
返回顶部
返回列表