Spring Event
Spring容器内置的事件如下
Event | Explanation |
---|---|
ContextRefreshedEvent Spring容器完成初始化完成后发布的容器事件。 初始化完成包括:bean加载完成,完成bean-post-processor,完成单例实例化,容器已准备完成,容器的Refresh事件可以被触发多次(热部署) |
Published when the ApplicationContext is initialized or refreshed (for example, by using the refresh() method on the ConfigurableApplicationContext interface). Here, “initialized” means that all beans are loaded, post-processor beans are detected and activated, singletons are pre-instantiated, and the ApplicationContext object is ready for use. As long as the context has not been closed, a refresh can be triggered multiple times, provided that the chosen ApplicationContext actually supports such “hot” refreshes. For example, XmlWebApplicationContext supports hot refreshes, but GenericApplicationContext does not. |
ContextStartedEvent 容器生命周期,容器开始启动触发 |
Published when the ApplicationContext is started by using the start() method on the ConfigurableApplicationContext interface. Here, “started” means that all Lifecycle beans receive an explicit start signal. Typically, this signal is used to restart beans after an explicit stop, but it may also be used to start components that have not been configured for autostart (for example, components that have not already started on initialization). |
ContextStoppedEvent 不常用 |
Published when the ApplicationContext is stopped by using the stop() method on the ConfigurableApplicationContext interface. Here, “stopped” means that all Lifecycle beans receive an explicit stop signal. A stopped context may be restarted through a start() call. |
ContextClosedEvent 不常用 |
Published when the ApplicationContext is being closed by using the close() method on the ConfigurableApplicationContext interface or via a JVM shutdown hook. Here, “closed” means that all singleton beans will be destroyed. Once the context is closed, it reaches its end of life and cannot be refreshed or restarted. |
RequestHandledEvent 不常用 |
A web-specific event telling all beans that an HTTP request has been serviced. This event is published after the request is complete. This event is only applicable to web applications that use Spring’s DispatcherServlet . |
ServletRequestHandledEvent 不常用 |
A subclass of RequestHandledEvent that adds Servlet-specific context information. |
发布事件
@Component
public class OnAppRefreshedListener implements ApplicationListener<ContextRefreshedEvent> {
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
System.err.println("#####OnAppRefreshedListener####");
}
}
发布自定义事件
To publish a custom ApplicationEvent
, call the publishEvent()
method on an ApplicationEventPublisher
. Typically, this is done by creating a class that implements ApplicationEventPublisherAware
and registering it as a Spring bean. The following example shows such a class:
定义事件
public class BlackListEvent extends ApplicationEvent {
private final String address;
private final String content;
public BlackListEvent(Object source, String address, String content) {
super(source);
this.address = address;
this.content = content;
}
// accessor and other methods...
}
业务中发布事件
@Service
public class EmailService implements ApplicationEventPublisherAware {
private List<String> blackList;
private ApplicationEventPublisher publisher;
public void setBlackList(List<String> blackList) {
this.blackList = blackList;
}
public void setApplicationEventPublisher(ApplicationEventPublisher publisher) {
this.publisher = publisher;
}
public void sendEmail(String address, String content) {
if (blackList.contains(address)) {
publisher.publishEvent(new BlackListEvent(this, address, content));
return;
}
// send email...
}
}
定义处理事件的Listener
实现ApplicationListener
public class BlackListNotifier implements ApplicationListener<BlackListEvent> {
private String notificationAddress;
public void setNotificationAddress(String notificationAddress) {
this.notificationAddress = notificationAddress;
}
public void onApplicationEvent(BlackListEvent event) {
// notify appropriate parties via notificationAddress...
}
}
注意点
Spring容器的默认的自定义发布事件机制是同步的,也就是说发布事件与Listener的执行是在同一个线程里。Debug截图如下:
Spring Boot Listener
除了可以使用Spring的Event与Listener还可以使用SpringBoot提供的机制
- 显示调用
SpringApplication.addListeners(…)
- 或显示调用
SpringApplicationBuilder.listeners(…)
- 让容器自动执行,可以把Listener放到META-INF/spring.factories目录中,配置内容如下:
org.springframework.context.ApplicationListener=com.example.project.MyListener