五、SpringBoot 监听机制

33 阅读2分钟

Java 监听机制

SpringBoot的监听机制,其实是对Java提供的事件监听机制的封装,Java中的事件监听机制定义了以下几个角色:

  • 事件:Event,继承java.util.EventObject类的对象
  • 事件源:Source,任意对象Object
  • 监听器:Listener,实现java.util.EventListener接口 的对象

SpringBoot监听机制

SpringBoot 在项目启动时,会对几个监听器进行回调,我们可以实现这几个监听器接口,在项目启动时完成一些操作.主要有以下四个监听器:

  • ApplicationContextlnitializer
  • SpringApplicationRunListener
  • CommandLineRunner
  • ApplicationRunner

创建一个模块实现上面四个监听器接口

截屏2024-04-22 16.59.43.png

@Component
public class MyApplicationContextInitializer implements ApplicationContextInitializer {
    @Override
    public void initialize(ConfigurableApplicationContext applicationContext) {
        System.out.println("ApplicationContextInitializer...run");
    }
}

public class MySpringApplicationRunListener implements SpringApplicationRunListener {
    public MySpringApplicationRunListener(SpringApplication application, String[] args) {
    }

    @Override
    public void starting(ConfigurableBootstrapContext bootstrapContext) {
        System.out.println("SpringApplicationRunListener...启动");
    }

    @Override
    public void environmentPrepared(ConfigurableBootstrapContext bootstrapContext, ConfigurableEnvironment environment) {
        System.out.println("环境准备");
    }

    @Override
    public void contextPrepared(ConfigurableApplicationContext context) {

        System.out.println("上下文对象准备");
    }

    @Override
    public void contextLoaded(ConfigurableApplicationContext context) {

        System.out.println("上下文对象加载");
    }

    @Override
    public void started(ConfigurableApplicationContext context, Duration timeTaken) {
        System.out.println("上下文对象加载完成");
    }

    @Override
    public void ready(ConfigurableApplicationContext context, Duration timeTaken) {
        System.out.println("项目启动完成,开始运行");
    }

    @Override
    public void failed(ConfigurableApplicationContext context, Throwable exception) {
        System.out.println("项目启动失败");
    }
}

/**
 * description: 当项目启动后执行 run 方法,可以用作缓存预热
 */

@Component
public class MyApplicationRunner implements ApplicationRunner {
    @Override
    public void run(ApplicationArguments args) throws Exception {
        System.out.println("ApplicationRunner...run");
        System.out.println(Arrays.asList(args.getSourceArgs()));
    }
}
@Component
public class MyCommandLineRunner implements CommandLineRunner {
    @Override
    public void run(String... args) throws Exception {
        System.out.println("CommandLineRunner...run");
        System.out.println(Arrays.asList(args));
    }
}

当我们传入参数启动项目时就会在控制台执行下面两个类中代码,在控制台打印

  • CommandLineRunner
  • ApplicationRunner
CommandLineRunner...run
[name=zhangsan]
ApplicationRunner...run
[name=zhangsan]

下面两个接口实现类想要生效,需要在自动配置文件中先进行指定配置

  • ApplicationContextlnitializer
  • SpringApplicationRunListener

截屏2024-04-22 18.52.37.png

org.springframework.context.ApplicationContextInitializer=\
cn.hxy.springbootlistener.listener.MyApplicationContextInitializer
org.springframework.boot.SpringApplicationRunListener=\
cn.hxy.springbootlistener.listener.MySpringApplicationRunListener

再次启动项目后可以看到 springboot 启动运行的生命周期

/Library/Java/JavaVirtualMachines/zulu-17.jdk/Contents/Home/bin/java -XX:TieredStopAtLevel=1 -Dspring.output.ansi.enabled=always -Dcom.sun.management.jmxremote -Dspring.jmx.enabled=true -Dspring.liveBeansView.mbeanDomain -Dspring.application.admin.enabled=true -Dmanagement.endpoints.jmx.exposure.include=* -javaagent:/Applications/IntelliJ IDEA.app/Contents/lib/idea_rt.jar=60403:/Applications/IntelliJ IDEA.app/Contents/bin -Dfile.encoding=UTF-8 -classpath /Users/hxy/code/java/IdeaProjects/springboot-listener/target/classes:/Users/hxy/devTools/apache-maven-3.6.3/repository/org/springframework/boot/spring-boot-starter/3.2.5/spring-boot-starter-3.2.5.jar:/Users/hxy/devTools/apache-maven-3.6.3/repository/org/springframework/boot/spring-boot/3.2.5/spring-boot-3.2.5.jar:/Users/hxy/devTools/apache-maven-3.6.3/repository/org/springframework/spring-context/6.1.6/spring-context-6.1.6.jar:/Users/hxy/devTools/apache-maven-3.6.3/repository/org/springframework/spring-aop/6.1.6/spring-aop-6.1.6.jar:/Users/hxy/devTools/apache-maven-3.6.3/repository/org/springframework/spring-beans/6.1.6/spring-beans-6.1.6.jar:/Users/hxy/devTools/apache-maven-3.6.3/repository/org/springframework/spring-expression/6.1.6/spring-expression-6.1.6.jar:/Users/hxy/devTools/apache-maven-3.6.3/repository/io/micrometer/micrometer-observation/1.12.5/micrometer-observation-1.12.5.jar:/Users/hxy/devTools/apache-maven-3.6.3/repository/io/micrometer/micrometer-commons/1.12.5/micrometer-commons-1.12.5.jar:/Users/hxy/devTools/apache-maven-3.6.3/repository/org/springframework/boot/spring-boot-autoconfigure/3.2.5/spring-boot-autoconfigure-3.2.5.jar:/Users/hxy/devTools/apache-maven-3.6.3/repository/org/springframework/boot/spring-boot-starter-logging/3.2.5/spring-boot-starter-logging-3.2.5.jar:/Users/hxy/devTools/apache-maven-3.6.3/repository/ch/qos/logback/logback-classic/1.4.14/logback-classic-1.4.14.jar:/Users/hxy/devTools/apache-maven-3.6.3/repository/ch/qos/logback/logback-core/1.4.14/logback-core-1.4.14.jar:/Users/hxy/devTools/apache-maven-3.6.3/repository/org/apache/logging/log4j/log4j-to-slf4j/2.21.1/log4j-to-slf4j-2.21.1.jar:/Users/hxy/devTools/apache-maven-3.6.3/repository/org/apache/logging/log4j/log4j-api/2.21.1/log4j-api-2.21.1.jar:/Users/hxy/devTools/apache-maven-3.6.3/repository/org/slf4j/jul-to-slf4j/2.0.13/jul-to-slf4j-2.0.13.jar:/Users/hxy/devTools/apache-maven-3.6.3/repository/jakarta/annotation/jakarta.annotation-api/2.1.1/jakarta.annotation-api-2.1.1.jar:/Users/hxy/devTools/apache-maven-3.6.3/repository/org/springframework/spring-core/6.1.6/spring-core-6.1.6.jar:/Users/hxy/devTools/apache-maven-3.6.3/repository/org/springframework/spring-jcl/6.1.6/spring-jcl-6.1.6.jar:/Users/hxy/devTools/apache-maven-3.6.3/repository/org/yaml/snakeyaml/2.2/snakeyaml-2.2.jar:/Users/hxy/devTools/apache-maven-3.6.3/repository/org/slf4j/slf4j-api/2.0.13/slf4j-api-2.0.13.jar cn.hxy.springbootlistener.SpringbootListenerApplication name=zhangsan
SpringApplicationRunListener...启动
环境准备

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v3.2.5)

ApplicationContextInitializer...run
上下文对象准备
2024-04-22T18:51:52.855+08:00  INFO 27596 --- [springboot-listener] [           main] c.h.s.SpringbootListenerApplication      : Starting SpringbootListenerApplication using Java 17.0.10 with PID 27596 (/Users/hxy/code/java/IdeaProjects/springboot-listener/target/classes started by hxy in /Users/hxy/code/java/IdeaProjects/springboot-condition)
2024-04-22T18:51:52.856+08:00  INFO 27596 --- [springboot-listener] [           main] c.h.s.SpringbootListenerApplication      : No active profile set, falling back to 1 default profile: "default"
上下文对象加载
2024-04-22T18:51:53.039+08:00  INFO 27596 --- [springboot-listener] [           main] c.h.s.SpringbootListenerApplication      : Started SpringbootListenerApplication in 0.306 seconds (process running for 0.49)
上下文对象加载完成
ApplicationRunner...run
[name=zhangsan]
CommandLineRunner...run
[name=zhangsan]
项目启动完成,开始运行

其实就是 springboot 在启动时会发布一些event 事件,实现监听接口就可以监听对应的事件,然后我们在实现类中编写代码即可对事件进行监听做一些操作