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

作者:Markey92 时间:2022-06-11 07:21:17 

注解说明

  • 使用注解: @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的实现组件中

来源:https://blog.csdn.net/u012578322/article/details/84112451

标签:SpringBoot,Bean,@PostConstruct
0
投稿

猜你喜欢

  • Flink支持哪些数据类型?

    2023-01-15 06:55:43
  • Java微信公众平台开发(13) 微信JSSDK中Config配置

    2022-12-29 15:58:24
  • spring mvc实现文件上传与下载功能

    2022-05-13 09:50:14
  • java中final与finally的使用介绍

    2023-04-21 05:36:43
  • Java使用组合模式实现表示公司组织结构功能示例

    2022-07-31 08:03:37
  • 使用Java和WebSocket实现网页聊天室实例代码

    2023-11-26 00:16:02
  • Java实现Word/Pdf/TXT转html的示例

    2023-09-03 19:57:42
  • c#实现哈夫曼树算法

    2022-11-24 08:25:02
  • Android四种数据存储的应用方式

    2023-07-25 05:01:06
  • Java集合系列之ArrayList源码分析

    2023-01-31 03:02:36
  • 用Java实现简单画板功能

    2023-01-19 08:17:10
  • Java 超详细讲解IO操作字节流与字符流

    2022-04-28 20:09:57
  • SpringBoot实现Mysql使用MD5进行密码加密的示例

    2022-11-24 23:14:16
  • Java SpringMVC数据响应超详细讲解

    2022-04-08 15:10:26
  • 使用栈的迷宫算法java版代码

    2022-03-07 12:47:16
  • java中form以post、get方式提交数据中文乱码问题总结

    2022-12-15 06:53:59
  • 详解Java内存泄露的示例代码

    2023-06-08 03:34:51
  • Iconfont(矢量图标)+iconmoon(图标svg互转)配合javascript实现社交分享系统

    2023-09-28 13:23:19
  • Java DecimalFormat 保留小数位及四舍五入的陷阱介绍

    2023-11-09 04:49:33
  • Java获取任意http网页源代码的方法

    2022-07-06 01:45:37
  • asp之家 软件编程 m.aspxhome.com