欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

浅谈SpringBoot中的Bean初始化方法 @PostConstruct

程序员文章站 2022-04-06 09:13:14
目录注解说明代码示例注解示例错误示例正确示例springboot @postconstruct虽好,也要慎用1 问题的产生2 案例模拟3 总结注解说明 使用注解: @postconstruct...

注解说明

  • 使用注解: @postconstruct
  • 效果:在bean初始化之后(构造方法和@autowired之后)执行指定操作。经常用在将构造方法中的动作延迟。
  • 备注:bean初始化时候的执行顺序: 构造方法 -> @autowired -> @postconstruct

代码示例

注解示例

@component
public class postconstructtest1 {
    @autowired
    postconstructtest2 postconstructtest2;
    public postconstructtest1() {
//        postconstructtest2.hello();
    }
    @postconstruct
    public void init() {
        // some init function
    }
}

在bean的初始化操作中,有时候会遇到调用其他bean的时候报空指针错误。这时候就可以将调用另一个bean的方法这个操作放到@postconstruct注解的方法中,将其延迟执行。

错误示例

    @component
    public class postconstructtest1 {
        @autowired
        postconstructtest2 postconstructtest2;
        public postconstructtest1() {
            postconstructtest2.hello();
        }
    }
    @component
    public class postconstructtest2 {
        public void hello() {
            system.out.println("hello, i am postconstructtest2");
        }
    }

浅谈SpringBoot中的Bean初始化方法 @PostConstruct

正确示例

    @component
    public class postconstructtest1 {
        @autowired
        postconstructtest2 postconstructtest2;
        public postconstructtest1() {
            postconstructtest2.hello();
        }
    }
@component
public class postconstructtest1 {
    @autowired
    postconstructtest2 postconstructtest2;
    public postconstructtest1() {
//        postconstructtest2.hello();
    }
    @postconstruct
    public void init() {
        postconstructtest2.hello();
    }
}

浅谈SpringBoot中的Bean初始化方法 @PostConstruct

springboot @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项目中建两个组件类componentone和componenttwo。耗时的初始化逻辑放在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 初始化完成后处理");
    }
}

启动应用,初始化部分日志如下:

浅谈SpringBoot中的Bean初始化方法 @PostConstruct

3 总结

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

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

以上为个人经验,希望能给大家一个参考,也希望大家多多支持。