使用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>