@PostConstruct及跳坑记录

@PostConstruct及跳坑记录

@PostConstruct的一个控制方法加载顺序的一个注解,如果使用恰当,可以方便解决很多问题,如果使用不当,也会出现一些认为莫名其妙的问题。

这里说一下@PostConstruct和@Autowired 一起使用的一些问题。

首先@PostConstruct是javax.annotation包下的注解,并不是Spring提供的。看一下servlet中的加载顺序。

graph TB 服务器加载Sevlet-->Servlet-Construct Servlet-Construct-->PostConstruct PostConstruct-->init init-->service service-->destroy destroy-->PreDestroy PreDestroy-->服务器卸载sevlet完毕

再来看一下Spring中的加载顺序:

graph LR Construct-->Autowired Autowired-->PostConstruct
  • @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;

}

通过这个示例,可以体会一下这些注解之间的微妙关系。

源码链接:https://gitee.com/chengluchao/graphql-clc/tree/master/test-post-construct/src/main/java/com/xplan/testpostconstruct

世界上所有的坑都是自己的无知造成的,想要避坑,就得不断提高自己的道行。

CLC

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值