Java Web项目中的Event

(1)Servlet的事件和监听器



*** Servlet、Filter、Listener 是单例的
*** 通过 @WebListener 或者 web.xml 来注册

(2)Spring 的 ApplicationEvent

引用
Publisher -> (ApplicationEvent) -> Listener


a)Spring内置事件
引用
ContextRefreshedEvent
ContextStartedEvent
ContextStoppedEvent
ContextClosedEvent
RequestHandledEvent


b)自定义事件
public class MyEvent extends ApplicationEvent {

  public MyEvent(Object source) {
    super(source);
  }

  // 可以定义任意参数的构造函数,用于传递需要的参数
}


c)事件监听@EventListener、ApplicationListener

spring4.1之前:
public class MyListener1 implements ApplicationListener<ContextClosedEvent> {
  @Override
  public void onApplicationEvent(ContextClosedEvent event) {
  }
}


从spring4.2开始可以
public class MyListener2 {
  @EventListener
  public void processContextStoppedEvent(ContextStoppedEvent event) {
  }
  @EventListener
  public void processContextClosedEvent(ContextClosedEvent event) {
  }
}


也可以同时捕获多个事件
@EventListener({ContextRefreshedEvent.class, ContextStoppedEvent.class, ContextStartedEvent.class})
public void handleContextEvent () {
}


d)发布事件ApplicationEventPublisher

@Autowired
private ApplicationEventPublisher eventPublisher;

eventPublisher.publishEvent(new MyEvent(this));


也可以通过在Listener中再次返回一个Event来继续发布一个事件,从而实现发布多个事件。
@EventListener
public MyAnotherEvent handleMyEvent(MyEvent event) {
    // ... 处理MyEvent
    return new MyAnotherEvent();
}


e)异步执行

Listener默认是在发布事件的线程中执行的。

通过@Async实现异步

把 @EventListener 标注的方法再标注 @Async 可实现异步执行。

通过ApplicationEventMulticaster实现异步
@Bean
ApplicationEventMulticaster applicationEventMulticaster() {
    SimpleApplicationEventMulticaster eventMulticaster = new SimpleApplicationEventMulticaster();
    eventMulticaster.setTaskExecutor(new SimpleAsyncTaskExecutor());
    eventMulticaster.setErrorHandler(TaskUtils.LOG_AND_SUPPRESS_ERROR_HANDLER);
    return eventMulticaster;
}


f)条件执行

从spring4.3开始正式提供基于 SpEL 来指定事件执行的条件
@EventListener(condition = "#myEvent.amount >= 100")
public void handleHighBids(MyEvent event) {
    // ...
}



g)@TransactionalEventListener

同步事件监听是的事务问题

比如需要在事务正确提交后在执行监听:
@TransactionalEventListener
public void handleAfterCommit(TaskScheduledEvent event)
    // ...
}


或者指定在事务的某状态时执行监听:
@TransactionalEventListener(phase = TransactionPhase.AFTER_ROLLBACK)
public void handleAfterRollback(TaskScheduledEvent event) {
   // ...
}



参考:
https://spring.io/blog/2015/02/11/better-application-events-in-spring-framework-4-2
http://zoltanaltfatter.com/2016/05/11/application-events-with-spring/
http://kimulla.hatenablog.com/entry/2016/09/23/125006

猜你喜欢

转载自rensanning.iteye.com/blog/2377751
今日推荐