前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >添加 SpringBoot 自定义启动代码的六种方式(下)

添加 SpringBoot 自定义启动代码的六种方式(下)

作者头像
用户3147702
发布2022-06-27 15:04:59
4380
发布2022-06-27 15:04:59
举报
文章被收录于专栏:小脑斧科技博客

1. 引言

上一篇文章中,我们介绍了六种 SpringBoot 启动时运行代码的方法,并且详细介绍了其中两个可以获取和处理 spring 启动参数的方法:

添加 SpringBoot 自定义启动代码的六种方式(上)

本文我们继续来介绍剩下的四种方式。

2. SpringBoot 启动事件与监听

2.1 SpringBoot 的启动事件

在 org.springframework.boot.context.event 包中,定义了 SpringBoot 的启动事件类:

  • ApplicationStartingEvent -- ApplicationContext 创建完成后触发。
  • ApplicationContextInitializedEvent -- Spring 项目启动时,已经完成 ApplicationContext 创建且调用所有的 ApplicationContextInitializers 接口的实现类后触发,但此时 bean 还尚未加载。
  • ApplicationPreparedEvent -- bean 全部创建完成后触发,但此时 ApplicationContext 还没有更新。
  • ApplicationStartedEvent -- ApplicationContext 完成更新后触发,但此时 ApplicationRunner 与 CommandLineRunner 接口的实现类还尚未被调用。
  • ApplicationReadyEvent -- 完成调用 ApplicationRunner 与 CommandLineRunner 接口的所有实现类后触发。
  • ApplicationFailedEvent -- 启动失败后触发。

有了上述启动的六个关键时刻触发的事件,我们就可以编写事件响应程序来实现自定义处理了。

可以看到,相较于上一篇文章中介绍的 ApplicationRunner 与 CommandLineRunner 接口,监听和响应启动事件让我们对项目的 启动有了更细粒度的控制。

除了上一篇文章中已经提到的 ApplicationRunner 与 CommandLineRunner 接口,上面还提到了 ApplicationContext、ApplicationContextInitializers 接口等,这些关键概念我们后续会有文章专门介绍,敬请期待下文。

2.2 编写事件响应代码

通过向注解 @EventListener 传入我们想要监听的事件类,就可以实现对这一事件的响应,例如:

代码语言:javascript
复制
 @Component
 public class RunAfterStartup{
 
 @EventListener(ApplicationReadyEvent.class)
 public void runAfterStartup() {
     System.out.println("Yaaah, I am running........");
 }

显然,我们不能像上一篇文章中那样轻松地获取启动参数了。

启动 SpringBoot,我们看到上述代码打印出了:

Yaaah, I am running........

3. 添加 @Postconstruct 注解

3.1 @Postconstruct 注解说明

也许你觉得编写事件响应太麻烦,那么,添加 @Postconstruct 注解的方式可能就是你想要的解决办法,这也是最常用的一种方法了。

只要在方法上加上这个 @Postconstruct 注解,这个方法就会在类创建完成后被立即调用。

3.2 使用 @Postconstruct 注解的限制

  1. 一个类中最多只能有一个方法添加 @Postconstruct 注解。
  2. @Postconstruct 注解修饰的方法不能具有参数和返回值,也不能是 static 方法。
  3. @Postconstruct 注解是 javaEE 的功能,而并非 Spring 的功能,因此,自 java11 不再默认包含 javaEE 开始,如果你想要使用这一功能,你需要手动添加 java.ee.ee 包到项目中。

3.2 示例

代码语言:javascript
复制
 @Component
 public class PostContructImpl {
 
   public PostContructImpl() {
     System.out.println("PostContructImpl Constructor called");
 }
 
   @PostConstruct
   public void runAfterObjectCreated() {
     System.out.println("PostContruct method called");
 }
 
 }

执行上述代码,打印出了:

PostContructImpl Constructor calledpostContruct method called

4. 实现 InitializingBean 接口

这种方法本质上和添加 @Postconstruct 注解是一样的。都会在这个类完成创建和初始化工作后调用。

我们只要实现 InitializingBean 的 afterPropertiesSet 方法即可。

例如:

代码语言:javascript
复制
 @Component
 public class InitializingBeanImpl implements InitializingBean {
     public InitializingBeanImpl() {
         System.out.println("InitializingBeanImpl Constructor called");
     }
     @Override
     public void afterPropertiesSet() throws Exception {
         System.out.println("InitializingBeanImpl afterPropertiesSet method called");
     }
 }

5. 通过 Bean 的 initMethod

5.1 简介

Spring 的 Bean 拥有一个属性 initMethod 可以让我们指定 bean 创建时的初始化方法,借助这个属性,我们就可以在其中添加我们想要的启动代码了。

5.2 注意事项

需要注意的是,这个 initMethod 必须是没有参数和返回值。但这个方法可以使 static 的甚至是 private 的。

5.3 示例

例如:

代码语言:javascript
复制
 public class BeanInitMethodImpl {
  
     public void runAfterObjectCreated() {
         System.out.println("yooooooooo......... someone called me");
     }
 } 
 
 @SpringBootApplication
 public class DemoApplication {
     public static void main(String[] args) {
         SpringApplication.run(DemoApplication.class, args);
     }
 
     @Bean(initMethod="runAfterObjectCreated")
     public BeanInitMethodImpl getFunnyBean() {
         return new BeanInitMethodImpl();
     }
  }

打印出了:

yooooooooo......... someone called me

6. 六种方法的执行顺序

上述的这些方法都是可以同时添加到你的项目中,那么,这些方法一旦同时添加,到底他们之间执行的先后顺序如何呢?

他们是按照下面的顺序来执行的:

  • Constructor
  • PostContruct method
  • afterPropertiesSet method
  • Bean init Method
  • ApplicationStartedEvent
  • ApplicationRunner Or CommandLineRunner
  • ApplicationReadyEvent

至于 ApplicationRunner 与 CommandLineRunner 的实现类,我们可以通过 @Order 注解决定他们之间的优先级。

附录 -- 参考资料

https://stacktraceguru.com/springboot/run-method-on-startup#application-runner

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-04-02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 小脑斧科技博客 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 引言
  • 2. SpringBoot 启动事件与监听
    • 2.1 SpringBoot 的启动事件
      • 2.2 编写事件响应代码
      • 3. 添加 @Postconstruct 注解
        • 3.1 @Postconstruct 注解说明
          • 3.2 使用 @Postconstruct 注解的限制
            • 3.2 示例
            • 4. 实现 InitializingBean 接口
            • 5. 通过 Bean 的 initMethod
              • 5.1 简介
                • 5.2 注意事项
                  • 5.3 示例
                  • 6. 六种方法的执行顺序
                  • 附录 -- 参考资料
                  领券
                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档