除了常见的 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);
}
}应用运行时,事件会以下面的次序发送:
在运行开始,但除了监听器注册和初始化以外的任何处理之前,会发送一 个 ApplicationStartedEvent
在 Environment 将被用于已知的上下文,但在上下文被创建前,会发送一个 ApplicationEnvironmentPreparedEvent
在refresh开始前,但在bean定义已被加载后,会发送一 个 ApplicationPreparedEvent
在 refresh 之后,相关的回调处理完,会发送一个 ApplicationReadyEvent,表示应用准备好接收请求了
启动过程中如果出现异常,会发送一个 ApplicationFailedEvent
注意:通常不需要使用 application 事件,但知道它们的存在是有用的(在某些场合可能会使用到),比如,在 Spring Boot 内部会使用事件处理各种任务。
该接口由应用程序事件监听器实现,且它继承 java.util.EventListener 接口,是一个标准的 Observer(观察者)设计模式。
从Spring 3.0开始,ApplicationListener 可以一般性地声明其感兴趣的事件类型。向 Spring ApplicationContext 注册后,将相应地过滤事件,并且仅针对匹配事件对象调用侦听器。
接口方法说明:
onApplicationEvent(E event):处理应用程序事件
ApplicationListener<PayloadApplicationEvent<T>> forPayload(Consumer<T> consumer):根据给定的有效 consumer 创建一个新的 ApplicationListener
该类由所有应用程序事件进行扩展,因为直接发布一般事件没有意义。源码如下:
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()");
}
}