Spring Boot 教程

Application 事件和监听器

除了常见的 Spring 框架事件,比如 ContextRefreshedEvent,SpringApplication 也会发送其他的 application 事件。

有些事件实际上是在 ApplicationContext 创建前触发的,所以你不能在那些事件(处理类)中通过 @Bean 注册监听器,只能通过 SpringApplication.addListeners(…) 或 SpringApplicationBuilder.lis teners(…) 方法注册。

如果想让监听器自动注册,而不关心应用的创建方式,你可以在工程中添加一个 META-INF/spring.factories 文件,并使用 org.springframework.context.ApplicationListener 作为key 指向那些监听器,如下:

# 注册自己的监听器
org.springframework.context.ApplicationListener=com.huangx.springboot.springapplication.MyListener

监听器 MyListener 的代码如下:

import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;

public class MyListener implements ApplicationListener {

    @Override
    public void onApplicationEvent(ApplicationEvent applicationEvent) {
        System.out.println("MyListener onApplicationEvent()");
    }
}

上面介绍了通过 META-INF/spring.factories 文件注册我们的事件,下面将介绍通过 SpringApplication 注册监听器:

import org.springframework.boot.Banner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;

@SpringBootApplication
public class SpringapplicationDemoApplication {

    public static void main(String[] args) {
        SpringApplication app = new SpringApplication(SpringapplicationDemoApplication.class);
        app.addListeners(new MyListener());
        app.setBannerMode(Banner.Mode.OFF);
        app.run(args);
    }

}

或者,使用 SpringApplicationBuilder 注册监听器,如下:

import org.springframework.boot.Banner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;

@SpringBootApplication
public class SpringapplicationDemoApplication {

    public static void main(String[] args) {
        new SpringApplicationBuilder().sources(ParentApplication.class)
                .child(SpringapplicationDemoApplication.class)
                .listeners(new MyListener())
                .bannerMode(Banner.Mode.OFF)
                .run(args);
    }

}

应用运行时,事件会以下面的次序发送: 

  1. 在运行开始,但除了监听器注册和初始化以外的任何处理之前,会发送一 个 ApplicationStartedEvent

  2. 在 Environment 将被用于已知的上下文,但在上下文被创建前,会发送一个 ApplicationEnvironmentPreparedEvent

  3. 在refresh开始前,但在bean定义已被加载后,会发送一 个 ApplicationPreparedEvent

  4. 在 refresh 之后,相关的回调处理完,会发送一个 ApplicationReadyEvent,表示应用准备好接收请求了

  5. 启动过程中如果出现异常,会发送一个 ApplicationFailedEvent

注意:通常不需要使用 application 事件,但知道它们的存在是有用的(在某些场合可能会使用到),比如,在 Spring Boot 内部会使用事件处理各种任务。

ApplicationListener 接口

该接口由应用程序事件监听器实现,且它继承 java.util.EventListener 接口,是一个标准的 Observer(观察者)设计模式。

从Spring 3.0开始,ApplicationListener 可以一般性地声明其感兴趣的事件类型。向 Spring ApplicationContext 注册后,将相应地过滤事件,并且仅针对匹配事件对象调用侦听器。

接口方法说明:

  • onApplicationEvent(E event):处理应用程序事件

  • ApplicationListener<PayloadApplicationEvent<T>> forPayload(Consumer<T> consumer):根据给定的有效 consumer 创建一个新的 ApplicationListener

ApplicationEvent 抽象类

该类由所有应用程序事件进行扩展,因为直接发布一般事件没有意义。源码如下:

public abstract class ApplicationEvent extends EventObject {

   /** use serialVersionUID from Spring 1.2 for interoperability. */
   private static final long serialVersionUID = 7099057708183571937L;

   /** System time when the event happened. */
   private final long timestamp;


   /**
    * Create a new {@code ApplicationEvent}.
    * @param source the object on which the event initially occurred or with
    * which the event is associated (never {@code null})
    */
   public ApplicationEvent(Object source) {
      super(source);
      this.timestamp = System.currentTimeMillis();
   }


   /**
    * Return the system time in milliseconds when the event occurred.
    */
   public final long getTimestamp() {
      return this.timestamp;
   }

}

在 Spring Boot 中提供了很多 ApplicationEvent 接口的实现,如:AbstractSubProtocolEvent、ApplicationContextEvent、BrokerAvailabilityEvent、PayloadApplicationEvent、RequestHandledEvent、TestContextEvent。我们可以再自己的监听器 onApplicationEvent() 方法中监听你想要监听的事件。

例如:在自己的监听器中监听 ApplicationStartingEvent 事件,代码如下:

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

public class MyListener implements ApplicationListener<ApplicationStartingEvent> {

    @Override
    public void onApplicationEvent(ApplicationStartingEvent applicationEvent) {
        System.out.println("MyListener onApplicationEvent()");
    }

}
说说我的看法
全部评论(
没有评论
关于
本网站属于个人的非赢利性网站,转载的文章遵循原作者的版权声明,如果原文没有版权声明,请来信告知:hxstrive@outlook.com
公众号