Spring Boot 应用程序生命周期扩展点妙用

前言

上一篇我们着重按照分类讲解了一下Spring Boot的常见扩展点,接下来我们讲解一下Spring Boot 的应用程序生命周期扩展点的一些妙用。

Spring Boot的应用程序生命周期扩展点是一些接口,可以让开发者在应用程序的不同生命周期阶段插入自己的逻辑。这些扩展点可以帮助开发者在应用程序启动、关闭、重启等阶段执行一些额外的操作。

下面介绍几个常用的应用程序生命周期扩展点:

  1. ApplicationRunner和CommandLineRunner:这两个接口可以在应用程序启动完成后执行一些初始化的操作。例如,你可以实现一个ApplicationRunner来初始化数据库连接池,或者实现一个CommandLineRunner来加载一些初始化数据。

  2. ApplicationPreparedEvent:这个事件在应用程序准备启动时触发,可以在其中执行一些准备工作。例如,你可以监听这个事件,然后在应用程序启动之前执行一些配置文件的加载操作。

  3. ApplicationStartedEvent:这个事件在应用程序开始启动时触发,可以在其中执行一些初始化的操作。例如,你可以监听这个事件,然后在应用程序启动之前执行一些初始化的逻辑。

  4. ApplicationReadyEvent:这个事件在应用程序完全启动后触发,可以在其中执行一些额外的初始化操作。例如,你可以监听这个事件,然后在应用程序启动之后执行一些数据缓存的加载操作。

  5. ApplicationFailedEvent:这个事件在应用程序启动失败时触发,可以在其中执行一些错误处理的逻辑。例如,你可以监听这个事件,然后在应用程序启动失败时发送一封错误报告邮件。

通过实现这些扩展点,你可以在应用程序的不同生命周期阶段插入自己的逻辑,并且可以方便地扩展和定制应用程序的行为。这些扩展点的使用可以帮助你更好地管理和控制应用程序的生命周期,提高应用程序的可靠性和可维护性。

还是那句老话,这个不是八股文,只有知道才遇到相似场景的才能知道怎么用。学以致用,是我们分享内容的不变的宗旨
在这里插入图片描述

冰点出品,必属精品


1. 应用程序生命周期扩展点

应用程序生命周期扩展点是指在Spring Boot应用程序的生命周期中,提供了一系列的扩展点,开发人员可以通过实现这些扩展点来对应用程序的生命周期进行控制和定制。这些扩展点主要包括以下几个:
在这里插入图片描述
此图来自网络

2. 使用场景示例

2.1 SpringApplicationRunListener

它是一个监听器接口,用于在Spring应用程序的运行生命周期中监听和响应相关事件。可以通过实现该接口来自定义应用程序的启动和关闭行为。
好的,让我们来看一个使用SpringApplicationRunListener的例子。

假设你正在开发一个在线学习平台的后端系统。在应用程序启动时,你想要执行一些特定的操作,例如加载配置文件、初始化数据库连接等。这时候,你可以使用SpringApplicationRunListener来监听应用程序的启动事件,并在事件触发时执行这些操作。

首先,需要创建一个名为CustomSpringApplicationRunListener的类,实现SpringApplicationRunListener接口,并重写相应的方法。CustomSpringApplicationRunListener类实现了SpringApplicationRunListener接口的各个方法。你可以根据需要在这些方法中执行特定的操作。例如,在starting方法中,你可以执行启动前的操作,如加载配置文件;在started方法中,你可以执行应用程序已启动的操作,如启动后台任务等。

import org.springframework.boot.SpringApplication;
import org.springframework.boot.SpringApplicationRunListener;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.ConfigurableEnvironment;

public class CustomSpringApplicationRunListener implements SpringApplicationRunListener {

    public CustomSpringApplicationRunListener(SpringApplication application, String[] args) {
    }

    @Override
    public void starting() {
        System.out.println("Application starting...");
        // 执行启动前的操作,如加载配置文件等
    }

    @Override
    public void environmentPrepared(ConfigurableEnvironment environment) {
        System.out.println("Environment prepared...");
        // 执行环境准备的操作,如设置环境变量等
    }

    @Override
    public void contextPrepared(ConfigurableApplicationContext context) {
        System.out.println("Context prepared...");
        // 执行上下文准备的操作,如初始化数据库连接等
    }

    @Override
    public void contextLoaded(ConfigurableApplicationContext context) {
        System.out.println("Context loaded...");
        // 执行上下文加载的操作,如配置Bean等
    }

    @Override
    public void started(ConfigurableApplicationContext context) {
        System.out.println("Application started...");
        // 执行应用程序已启动的操作,如启动后台任务等
    }

    @Override
    public void running(ConfigurableApplicationContext context) {
        System.out.println("Application running...");
        // 执行应用程序运行的操作,如执行定时任务等
    }

    @Override
    public void failed(ConfigurableApplicationContext context, Throwable exception) {
        System.out.println("Application failed to start...");
        // 执行应用程序启动失败的操作,如记录错误日志等
    }
}

接下来,需要在应用程序的META-INF目录下创建一个名为spring.factories的文件,并在其中配置CustomSpringApplicationRunListener类。

org.springframework.boot.SpringApplicationRunListener=com.example.CustomSpringApplicationRunListener

这样,当你的应用程序启动时,Spring Boot将会自动创建CustomSpringApplicationRunListener实例,并在适当的时机调用对应的方法。

这只是一个简单的例子,展示了如何使用SpringApplicationRunListener接口来监听应用程序的启动事件,并在事件触发时执行特定的操作 。实际项目可能需要考虑的问题更多,比如加载顺序,依赖关系等等。

2.2 ApplicationEnvironmentPreparedEvent

该事件在应用程序启动前触发,用于在环境准备阶段执行一些操作,例如:加载配置文件、设置系统属性等。
当应用程序的环境准备就绪时,可以使用ApplicationEnvironmentPreparedEvent来执行某些操作。例如,假设你正在开发一个基于Spring Boot的社交媒体应用程序,你可以使用这个事件来加载特定环境的配置文件,以便根据不同的环境配置进行不同的操作。

在这个例子中,我们可以通过创建一个实现了ApplicationListener接口的类来监听ApplicationEnvironmentPreparedEvent事件。然后在onApplicationEvent方法中,我们可以根据当前的环境配置加载不同的配置文件。可能举的事例不是很合理,大家能够理解就OK。

import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent;
import org.springframework.context.ApplicationListener;

public class EnvironmentPreparedListener implements ApplicationListener<ApplicationEnvironmentPreparedEvent> {

    @Override
    public void onApplicationEvent(ApplicationEnvironmentPreparedEvent event) {
        String environment = event.getEnvironment().getActiveProfiles()[0];
        
        // 根据环境配置加载不同的配置文件
        if (environment.equals("dev")) {
            // 加载dev环境的配置文件
        } else if (environment.equals("prod")) {
            // 加载prod环境的配置文件
        } else if (environment.equals("windows")) {
            // 加载prod环境的配置文件
        } else if (environment.equals("linux")) {
            // 加载prod环境的配置文件
        }
        
        // 执行其他操作
    }
}

在Spring Boot应用程序的入口类中,我们可以将这个监听器注册到Spring容器中:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class SocialMediaApplication {

    public static void main(String[] args) {
        SpringApplication application = new SpringApplication(SocialMediaApplication.class);
        application.addListeners(new EnvironmentPreparedListener());
        application.run(args);
    }
}

这样,当应用程序的环境准备就绪时,EnvironmentPreparedListener中的onApplicationEvent方法将会被触发,你可以在该方法中执行一些特定于环境配置的操作,例如加载特定的配置文件。这在开发和部署应用程序时非常有用,可以根据不同的环境配置进行不同的初始化操作。

2.3 ApplicationPreparedEvent

该事件在应用程序上下文创建完成后触发,用于在应用程序准备阶段执行一些操作,例如:创建和初始化Bean等。

好的,我可以举一个使用ApplicationPreparedEvent的例子。

假设你正在开发一个电子商务网站的后端系统,当应用程序启动时,你希望自动初始化一些商户数据到缓存中。

首先,你需要创建一个实现ApplicationListener接口的类,用于监听ApplicationPreparedEvent事件。例如,你可以创建一个名为DataInitializationListener的类:

import org.springframework.boot.context.event.ApplicationPreparedEvent;
import org.springframework.context.ApplicationListener;

public class DataInitializationListener implements ApplicationListener<ApplicationPreparedEvent> {

    @Override
    public void onApplicationEvent(ApplicationPreparedEvent event) {
        // 在应用程序准备阶段执行初始化数据的操作
        initializeData();
    }

    private void initializeData() {
        // 在这里执行初始化数据的逻辑,例如将商户数据加载到缓存中去
        // ...
    }
}

然后,在你的Spring Boot应用程序的主类中,将DataInitializationListener注册为一个bean,以便在应用程序启动时被自动调用:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
public class YourApplication {

    public static void main(String[] args) {
        SpringApplication.run(YourApplication.class, args);
    }

    @Bean
    public DataInitializationListener dataInitializationListener() {
        return new DataInitializationListener();
    }
}

现在, 运行应用程序时,DataInitializationListener将会监听ApplicationPreparedEvent事件,并在应用程序准备阶段执行initializeData方法,从而实现自动初始化商户数据的功能。

ApplicationPreparedEvent事件是在应用程序准备阶段触发的,该阶段是在ApplicationContext创建之前,但已经加载了bean定义。因此,你可以在该事件中执行与应用程序初始化相关的操作。

2.4 ApplicationStartedEvent

该事件在应用程序启动完成后触发,用于在应用程序启动后执行一些操作,例如:向日志中输出启动信息等。

2.5 ApplicationReadyEvent

该事件在应用程序准备就绪后触发,用于在应用程序运行期间执行一些操作,例如:启动定时任务、初始化缓存等。

2.6 ApplicationFailedEvent

该事件在应用程序启动失败后触发,用于在应用程序启动失败时执行一些操作,例如:记录日志、发送告警等。

当应用程序启动失败时,可以使用ApplicationFailedEvent事件来发送通知或记录日志,以便进行故障排查和问题解决。例如,假设我们的应用程序依赖于数据库连接,如果数据库连接失败导致应用程序无法启动,我们可以创建一个监听器类来处理这种情况。下面是一个简单的例子:

创建一个实现ApplicationListener接口的监听器类,例如ApplicationFailedListener:

import org.springframework.boot.context.event.ApplicationFailedEvent;
import org.springframework.context.ApplicationListener;

public class ApplicationFailedListener implements ApplicationListener<ApplicationFailedEvent> {

    @Override
    public void onApplicationEvent(ApplicationFailedEvent event) {
        // 获取失败的异常信息
        Throwable throwable = event.getException();
        
        // 发送通知或记录日志,进行故障排查和问题解决
        System.out.println("应用程序启动失败:" + throwable.getMessage());
    }
}

然后,在Spring Boot应用程序的入口类中,将该监听器类注册为一个Bean:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(Application.class, args);

        // 其他应用程序逻辑
    }

    @Bean
    public ApplicationFailedListener applicationFailedListener() {
        return new ApplicationFailedListener();
    }
}

现在,当应用程序启动失败时,ApplicationFailedListener监听器中的onApplicationEvent方法将被调用,并打印出失败的异常信息。

这个例子只是一个简单的示例,你可以根据实际需求进行扩展和定制化。你可以根据具体的业务场景,使用该事件来发送邮件、短信通知、记录日志或进行其他故障处理操作。

2.7 ApplicationRunner

可以利用ApplicationRunner接口来执行一些应用程序启动后的初始化任务。

@Component
public class MyApplicationRunner implements ApplicationRunner {

    @Override
    public void run(ApplicationArguments args) throws Exception {
        // 在应用程序启动后执行的任务
        System.out.println("应用程序启动后执行的任务");
        // 可以在这里执行一些初始化操作,如加载配置文件、初始化数据库连接等
    }
}

我们创建了一个名为MyApplicationRunner的类,并实现了ApplicationRunner接口。在类中,我们重写了run方法,该方法会在应用程序启动后被自动调用。在run方法中,可以编写需要在应用程序启动后执行的任务。例如,可以在这里加载配置文件、初始化数据库连接、创建一些初始数据等。

要让Spring Boot应用程序自动执行该任务,需要将MyApplicationRunner类注解为一个@Component或者@Service等Spring Bean,并将其注册到Spring容器中。这样,当应用程序启动时,Spring Boot会自动调用MyApplicationRunner的run方法。

这样 也就可以利用ApplicationRunner接口来执行一些应用程序启动后的初始化任务。

3. 参考文档

  1. Spring Boot官方文档:https://spring.io/projects/spring-boot
  2. Spring Boot Reference Guide:https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/
  3. Spring Boot官方文档相关 https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-customizing-bean-definitions
  4. Spring Boot 自动配置 https://docs.spring.io/spring-boot/docs/3.1.2/reference/html/auto-configuration-classes.html#appendix.auto-configuration-classes

在这里插入图片描述

👏好了,本次的Spring Boot 的扩展点分享就到这儿,我是冰点,下次见。如果我的文章对你有所收获,可以给个赞。如果有疑问可以在评论区留言。
在这里插入图片描述

  • 49
    点赞
  • 48
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 27
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

冰点.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值