Skip to content

监听机制原理分析

SpringBoot的监听机制,本质上是对Java提供的事件监听机制的封装

Java中事件的监听机制定义了以下几个角色:

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

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

  • ApplicationContextInitializer

    java
    package com.jlc.springbootlistener.listener;
    
    import org.springframework.ApplicationContextInitializer;
    
    public class MyApplicationContextInitializer implements ApplicationContextInitializer {
        // 在项目没有检测IOC容器时执行
        @Override
        public void initialize(ConfigurableApplicationContext applicationContext) {
            System.out.println("ApplicationContextInitializer监听器正在执行...");
        }
    }

    执行监听器需要我们进行注册,在resources文件夹中创建META-INF文件夹,内部新建spring.factories文件,其配置内容为:

    properties
    org.springframework.ApplicationContextInitializer=com.jlc.springbootlistener.listener.MyApplicationContextInitializer
  • SpringApplicationRunListener

    java
    package com.jlc.springbootlistener.listener;
    
    import org.springframework.boot.SpringApplicationRunListener;
    import org.springframework.core.env.ConfigurableEnvironment;
    import org.springframework.context.ConfigurableApplicationContext;
    
    // 在SpringBoot启动过程中的不同阶段,可以去监听不同的事件
    public class MySpringApplicationRunListener implements SpringApplicationRunListener {
        // 编写一个构造方法,如果不写,程序会报错
        public MySpringApplicationRunListener(StringApplication application, String[] args) {}
        
        @Override
        // 程序启动时执行
        public void starting() {   
            System.out.println("项目启动中...");
        }
        
        @Override
        // 环境准备前执行
        public void environmentPrepared(ConfigurableEnvironment environment) {
            System.out.println("环境对象开始准备...");
        }
        
        @Override
        // 上下文IOC容器准备前执行
        public void contextPrepared(ConfigurableApplicationContext context) {
            System.out.println("上下文对象开始准备...");
        }
        
        @Override
        // 上下文IOC容器开始加载执行
        public void contextLoaded(ConfigurableApplicationContext context) {
            System.out.println("上下文对象开始加载...");
        }
        
        @Override
        // 程序启动完成执行
        public void started(ConfigurableApplicationContext context) {
            System.out.println("上下文对象加载完成...");
        }
        
        @Override
        // 程序运行时执行
        public void running(ConfigurableApplicationContext context) {
            System.out.println("项目启动完成,开始运行...");
        }
        
        @Override
        // 程序运行失败执行
        public void failed(ConfigurableApplicationContext context, Throwable exception) {
            System.out.println("项目启动失败...");
        }
    }

    执行监听器需要我们进行注册,在resources文件夹中创建META-INF文件夹,内部新建spring.factories文件,其配置内容为:

    properties
    org.springframework.boot.SpringApplicationRunListener=com.jlc.springbootlistener.listener.MySpringApplicationRunListener
  • CommandLineRunner

    java
    package com.jlc.springbootlistener.listener;
    
    import org.springframework.boot.CommandLineRunner;
    import org.springframework.stereotype.Component;
    
    @Component   // 注册到Spring容器中
    public class MyCommandLineRunner implements CommandLineRunner {
        @Override
        public void run(String... args) throws Exception {
            System.out.println("CommandLineRunner run...");
            // 同时可以打印命令行参数args
            System.out.println(Arrays.asList(args));
        }
    }

    直接放到IOC容器中会自动的调用,在项目启动后执行对应的输出语句

  • ApplicationRunner

    java
    package com.jlc.springbootlistener.listener;
    
    import org.springframework.boot.ApplicationArguments;
    import org.springframework.boot.ApplicationRunner;
    import org.springframework.stereotype.Component;
    
    @Component   // 注册到Spring容器中
    public class MyApplicationRunner implements ApplicationRunner {
        @Override
        public void run(ApplicationArguments args) throws Exception {
            System.out.println("ApplicationRunner run...");
            // 同时可以打印命令行参数args
            System.out.println(Arrays.asList(args.getSourceArgs()));
        }
    }

    直接放到IOC容器中会自动的调用,在项目启动后执行对应的输出语句

Released under the MIT License.