Spring专题

使用Spring事件和观察者模式案例

使用Spring事件和观察者模式源码下载

观察者模式的本质是"对象之间定义一个一对多的依赖,这样,当一个对象的状态发生改变,其所有监听者得到通知,见Gof观察者模式

Spring通过ApplicationEvent类和ApplicationListener的接口提供ApplicationContext的事件处理。如果一个bean实现了ApplicationListener的接口并被部署到,如果容器内发生了ApplicationEvent,这个监听bean将收到它。Spring自带了内置事件ContextStartedEvent ContextStoppedEvent,你也可以创建自己的自定义事件。

使用观察者模式,有三个类是必须的:

观察者是接受事件的,必须实现ApplicationListener 类. 可观察Observable类是负责发送事件的,必须实现 ApplicationEventPublisherAware. 最后事件必须继承ApplicationEvent.

首先,事件代码:

public class MessageEvent extends ApplicationEvent {

 **
  *
  *
 private static final long serialVersionUID = 5743058377815147529L;

 private String message;

 public MessageEvent(Object source, String message) {
  super(source);
  this.message = message;
 }

 @Override
 public String toString() {
  StringBuilder builder = new StringBuilder();
  builder.append('MessageEvent [message=').append(message).append(']');
  return builder.toString();
 }

}

负责发送事件的producer,也就是可观察者observable:

public class EventSource implements Runnable, ApplicationEventPublisherAware {

 private ApplicationEventPublisher applicationEventPublisher = null;

 public void setApplicationEventPublisher(
   ApplicationEventPublisher applicationEventPublisher) {
  this.applicationEventPublisher = applicationEventPublisher;
 }

 public void run() {
  final InputStreamReader isr = new InputStreamReader(System.in);
  final BufferedReader br = new BufferedReader(isr);
  while (true) {
   try {
    String response = br.readLine();
    System.out.println(Thread.currentThread().getName());
    this.applicationEventPublisher.publishEvent(new MessageEvent(this, response));
   } catch (IOException e) {
    e.printStackTrace();
   }
  }
 }
}

观察者observer是监听者,事件的消费者consumer:

public class ResponseHandler implements ApplicationListener<MessageEvent> {

 public void onApplicationEvent(MessageEvent messageEvent) {

  System.out.println(Thread.currentThread().getName());
  System.out.println(messageEvent);
 }

}

客户端调用:

public class MyApp {

 public static void main(String args[]) {

  ApplicationContext applicationContext = new ClassPathXmlApplicationContext('classpath:META-INFspringapp-context.xml');

  EventSource eventSource = applicationContext.getBean('eventSource', EventSource.class);
  Thread thread = new Thread(eventSource);
  thread.start();

 }

}

Spring的配置:

<beans xmlns='http:www.springframework.orgschemabeans' xmlns:xsi='http:www.w3.org2001XMLSchema-instance' xmlns:context='http:www.springframework.orgschemacontext' xmlns:task='http:www.springframework.orgschematask' xsi:schemaLocation='http:www.springframework.orgschematask http:www.springframework.orgschemataskspring-task-3.0.xsd http:www.springframework.orgschemabeans http:www.springframework.orgschemabeansspring-beans-3.0.xsd http:www.springframework.orgschemacontext http:www.springframework.orgschemacontextspring-context-3.0.xsd'>
  <bean id='eventSource' class='org.asotobu.oo.EventSource' >
  <bean id='responseHandler' class='org.asotobu.oo.ResponseHandler' >
  <task:executor id='pool' pool-size='10' >
  <bean id='applicationEventMulticaster'        class='org.springframework.context.event.SimpleApplicationEventMulticaster'>
      <property name='taskExecutor' ref='pool' >
  <bean>
<beans>

 

 

在Spring中使用异步事件实现同步事务

EDA事件驱动架构