ApplicationContext中的事件处理是通过ApplicationEvent类和ApplicationListener接口来提供的。如果一个实现ApplicationListener接口的bean被部署到上下文中,每当ApplicationEvent发布到ApplicationContext时,都会通知该bean。这是标准的观察者模式(Observer)。
spring4.2开始提供了基于注解的模型及发布任意事件的能力,这是一个不一定从ApplicationEvent扩展的对象。
spring提供了以下标准事件:
1)ContextRefreshedEvent:当ApplicationContext被初始化或刷新时触发该事件。
2)ContextClosedEvent:当ApplicationContext关闭时触发该事件,容器关闭时其管理的所有单例bean都被销毁。
3)ContextStartedEvent:当容器调用start()时触发该事件。
4)ContextStoppedEvent:当容器调用stop()时触发该事件。
5)RequestHandleEvent:在WEB应用中,当一个HTTP请求结束时触发该事件。
自定义事件
自定义事件只需继承ApplicationEvent类即可。

要发布自定义的ApplicationEvent,需要在ApplicationEventPublisher上调用publishEvent(event)方法。通过创建一个实现了ApplicationEventPublisherAware接口的类,并将其注册为一个spring bean来完成。如下:

在配置时spring容器会检测到UserService实现了ApplicationEventPublisherAware接口,并自动调用setApplicationEventPublisher()。传入的参数是spring容器本身,我们只需通过ApplicationEventPublisher接口与应用程序上下文交互即可。
创建一个实现ApplicationListener接口的类MyEventListener,用来接收自定义的ApplicationEvent,并将其注册为一个spring bean。如下:

基于注解的事件模型
自spring4.2开始可以通过EventListener注解,在托管bean的任何公共方法上注册一个事件监听器,如下:

方法签名再次声明它监听的事件类型,使用灵活的名称而不实现特定的监听器接口。事件类型也可通过泛型来缩小,只要实际事件类型在其实现层次结构中解析泛型参数即可。
若一个方法应该监听几个事件,或根本没有参数定义它,则可以在注解本身上指定事件类型,如下:


异步处理事件
如果需要异步处理事件,只需重用@Async注解即可。此时TestEvent会被作为一个独立的线程处理。如下:

处理异步事件时的限制:
1)若事件监听抛出异常,该事件不会被传递给调用者。
2)这样的监听器不能发送回复,若需要发送另一个事件作为处理结果,需要注入ApplicationEventPublisher手动发送事件。
--参考文献《Srping5开发大全》
网友评论