Spring Boot:@PostConstruct虽好,也要慎用

做过SpringBoot开发的话,肯定对@PostConstruct比较熟悉。在一个Bean组件中,标记了@PostConstruct的方法会在Bean构造完成后自动执行方法的逻辑。

1 问题的产生

先说下SpringBoot中Bean的加载过程,简单点说就是SpringBoot会把标记了Bean相关注解(例如@Component、@Service、@Repository等)的类或接口自动初始化全局的单一实例,如果标记了初始化顺序会按照用户标记的顺序,否则按照默认顺序初始化。在初始化的过程中,执行完一个Bean的构造方法后会执行该Bean的@PostConstruct方法(如果有),然后初始化下一个Bean。

那么: 如果@PostConstruct方法内的逻辑处理时间较长,就会增加SpringBoot应用初始化Bean的时间,进而增加应用启动的时间。因为只有在Bean初始化完成后,SpringBoot应用才会打开端口提供服务,所以在此之前,应用不可访问

2 案例模拟

为了模拟上面说的情况,在SpringBoot项目中建两个组件类ComponentOneComponentTwo。耗时的初始化逻辑放在ComponentOne中,并设置ComponentOne的初始化顺序在ComponentTwo之前。完整代码如下:

@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class ComponentOne {
    private Logger logger = LoggerFactory.getLogger(this.getClass());

    public ComponentOne() {
        this.logger.info("ComponentOne 初始化完成");
    }

    @PostConstruct
    public void init() {
        this.logger.info("ComponentOne 模拟耗时逻辑开始");
        try {
        	//这里休眠5秒模拟耗时逻辑
            Thread.sleep(1000 * 5);
        } catch (InterruptedException e) {
            logger.info("模拟逻辑耗时失败", e);
        }
        this.logger.info("ComponentOne 模拟耗时逻辑完成");
    }
}

@Component
@Order(Ordered.HIGHEST_PRECEDENCE + 1)
public class ComponentTwo {
    private Logger logger = LoggerFactory.getLogger(this.getClass());

    public ComponentTwo() {
        this.logger.info("ComponentTwo 初始化完成");
    }

    @PostConstruct
    public void init() {
        this.logger.info("ComponentTwo 初始化完成后处理");
    }
}

启动应用,初始化部分日志如下:
在这里插入图片描述

3 总结

所以,如果应用有一些初始化操作,有以下几点建议:

  • 轻量的逻辑可放在Bean的@PostConstruct方法中
  • 耗时长的逻辑如果放在@PostConstruct方法中,可使用独立线程执行
  • 初始化操作放在CommandLineRunner或ApplicationRunner的实现组件中1

  1. 参考<<Spring Boot:应用启动数据初始化接口CommandLineRunner和ApplicationRunner>> ↩︎

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值