本文我们讨论如何使用spring event。事件是spring中容易被忽略的功能,但也是最有用的功能之一。和其他的spring特性一样,事件发布功能由ApplicationContext提供。
事件遵循下面几点简单约定:
- 事件应该继承自 ApplicationEvent
- 发布类应该注入 ApplicationEventPublisher 对象
- 监听器应该实现 ApplicationListener 接口
spring 允许创建和发布自定义事件,默认情况下事件是同步机制。同步机制有一定的优势,如监听器能够和发布处于同一个事务上下文。
下面创建一个简单事件类——用于存储事件数据。本例中事件类包括字符串消息属性:
public class CustomSpringEvent extends ApplicationEvent {
private String message;
public CustomSpringEvent(Object source, String message) {
super(source);
this.message = message;
}
public String getMessage() {
return message;
}
}
现在我们创建事件发布类。发布类构造事件对象并发布给相应的监听器。为了发布事件,发布类可以简单注入ApplicationEventPublisher对象,然后使用其publishEvent() API发布事件:
public class CustomSpringEventPublisher {
@Autowired
private ApplicationEventPublisher applicationEventPublisher;
public void doStuffAndPublishAnEvent(final String message) {
System.out.println("Publishing custom event. ");
CustomSpringEvent customSpringEvent = new CustomSpringEvent(this, message);
applicationEventPublisher.publishEvent(customSpringEvent);
}
}
另外,发布类也可以实现ApplicationEventPublisherAware接口,在应用启动时注入applicationEventPublisher对象。通常使用@Autowire注解注入更简单。
最后,我们创建监听器。仅需要监听器是实现ApplicationListener接口的bean即可:
@Component
public class CustomSpringEventListener implements ApplicationListener<CustomSpringEvent> {
@Override
public void onApplicationEvent(CustomSpringEvent event) {
System.out.println("Received spring custom event - " + event.getMessage());
}
}
注意到我们自定义监听器是使用自定义事件泛型实现参数化,使用onApplicationEvent() 方法类型安全。这将避免不得不检查对象为特定事件的实例及类型转换。
前面已经提及缺省spring事件是同步的,doStuffAndPublishAnEvent()方法是阻塞,直到监听器完成事件处理。
有些场景,同步机制发布事件不能满足我们需求——可能需要采用异步方式处理事件。通过创建带executor的ApplicationEventMulticaster bean开启异步机制;下面定义SimpleAsyncTaskExecutor:
@Configuration
public class AsynchronousSpringEventsConfig {
@Bean(name = "applicationEventMulticaster")
public ApplicationEventMulticaster simpleApplicationEventMulticaster() {
SimpleApplicationEventMulticaster eventMulticaster
= new SimpleApplicationEventMulticaster();
eventMulticaster.setTaskExecutor(new SimpleAsyncTaskExecutor());
return eventMulticaster;
}
}
事件、发布类和监听器实现和之前示例一样,但现在监听器将采用异步方式在不同线程中处理事件。
spring自身默认会发布不同的内置事件,比如ApplicationContext 会触发不同的框架事件,包括 ContextRefreshedEvent, ContextStartedEvent, RequestHandledEvent 等。
这些事件为应用程序开发人员提供了可将应用程序的生命周期和上下文关联起来,并在必要时添加自定义逻辑。下面示例是监听上下文刷新事件:
public class ContextRefreshedListener
implements ApplicationListener<ContextRefreshedEvent> {
@Override
public void onApplicationEvent(ContextRefreshedEvent cse) {
System.out.println("Handling context re-freshed event. ");
}
}
本文介绍了spring事件处理机制——创建自定义事件、发布事件以及在监听器中处理事件。也简要介绍了配置异步处理事件。