@PostConstruct及跳坑记录
@PostConstruct及跳坑记录
@PostConstruct的一个控制方法加载顺序的一个注解,如果使用恰当,可以方便解决很多问题,如果使用不当,也会出现一些认为莫名其妙的问题。
这里说一下@PostConstruct和@Autowired 一起使用的一些问题。
首先@PostConstruct是javax.annotation包下的注解,并不是Spring提供的。看一下servlet中的加载顺序。
再来看一下Spring中的加载顺序:
- @Autowired是在构造方法执行之后开始执行的
- @PostConstruct是在依赖注入完成后开始执行
举一个跳坑的例子
场景
两个service:Aservice和Bservice,一个bean:Cbean;
在Bservice中的@PostConstruct方法中动态注入一个对象Cbean,Aservice中需要依赖Cbean。
跳坑演示
public class Cbean {
private int id;
private String name;
}
Bservie中的一个PostConstruct方法动态注册Cbean到spring中
@Component
public class Bservie {
@Autowired
private ApplicationContext context;
@PostConstruct
public void init() {
Cbean c = new Cbean();
c.setId(1);
c.setName("name");
//获取BeanFactory
DefaultListableBeanFactory defaultListableBeanFactory = (DefaultListableBeanFactory) context.getAutowireCapableBeanFactory();
//动态注册bean.
defaultListableBeanFactory.registerSingleton("cbean",c);
}
}
Aservice中需要注入Cbean
@Component
public class Asevice {
@Autowired
private Cbean cbean;
@Autowired
private Bservie bservie;
}
这里的AService的加载顺序为:构造器-->Autowired Cbean;
此时Bservice中的PostConstruct还没有触发执行,所以spring池中没有Cbean,自然抛出异常:
Field cbean in com.xplan.testpostconstruct.Asevice required a bean of type 'com.xplan.testpostconstruct.Cbean' that could not be found.
当然,如Aservice中有多个Autowired,加载顺序是从上到下的。
这个困局的解法只需要把Aservice中的两个属性调整下顺序即可,这样就先加载Bservie,在创建Bservie的过程中会触发PostConstruct的方法,自然此局就解了。
@Component
public class Asevice {
@Autowired
private Bservie bservie;
@Autowired
private Cbean cbean;
}
通过这个示例,可以体会一下这些注解之间的微妙关系。
世界上所有的坑都是自己的无知造成的,想要避坑,就得不断提高自己的道行。
CLC
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析