事件处理一般都采用类似观察者模式, java util自带了观察者模式的接口
1、观察者模式接口
关于观察者这个模式, 可以参见本博《设计模式 精华一页纸》, JDK 提供的这个接口, 可以方便的进行开发 java.util.Observable -- 事件发布者 (目标) java.util.Observer -- 事件监听者 (观察者)
2、事件处理接口
EventObject - 事件对象 EventListener - 事件监听对象
接口虽然简单, 但java的事件都是基于如上的接口, 比如典型 GUI 的awt事件
要完成一个完整的事件模型 就需要结合 观察者模式 + 事件处理接口,即包含三个部分:事件、事件发布者、监听者
3、Spring 的事件派发模型
事件 ApplicationEvent -> 继承 EventObject 监听者 ApplicationListener -> 继承 EventListener 事件管理者/发布者 ApplicationEventPublisher | ApplicationEventMulticaster, 这是JDK 事件未提供的模块
I、实例 a、事件 public class LogEvent extends ApplicationEvent{ public LogEvent(Log source) { super(source); } @Override public Log getSource(){ return (Log)super.getSource(); } }
b、监听者 public class LogListener implements ApplicationListener<LogEvent>{ @Override public void onApplicationEvent(LogEvent event) { System.out.println("get event : " + event.getSource()); } }
c、事件发布者 public class LogPublisher implements ApplicationEventPublisher{ private List<ApplicationListener<ApplicationEvent>> listeners = new LinkedList<ApplicationListener<ApplicationEvent>>(); @Override public void publishEvent(ApplicationEvent event) { for(ApplicationListener<ApplicationEvent> listener : listeners) listener.onApplicationEvent(event); } public void addListener(ApplicationListener<ApplicationEvent> listener){ listeners.add(listener); } }
应用 noSpring ApplicationEvent event = new LogEvent(log); ApplicationListener listener = new LogListener(); LogPublisher pub = new LogPublisher(); pub.addListener(listener); pub.publishEvent(event); Spring ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("ApplicationContext.xml"); context.addApplicationListener(listener); context.publishEvent(event);
II、Spring的体系 常用的事件
事件发布者/管理者 ApplicationEventPublisher ApplicationEventMulticaster -- AbstractApplicationContext -- XXXApplicationContext
监听者 ApplicationListener SmartApplicationListener -- 可以支持按顺序调用
III、增强调用(结合 Spring 任务调度机制) 因为Spring 观察者模式采用的是 推的方式,所以 如果某个任务执行很慢, 就会卡住, 所以Spring提供了异步调用的机制, SimpleApplicationEventMulticaster, 通知任务都是以异步方式执行 <task:executor id="taskExecutor" pool-size="1-4" queue-capacity="128" /> <bean id="applicationEventMulticaster" class="org.springframework.context.event.SimpleApplicationEventMulticaster"> <property name="taskExecutor" ref="taskExecutor"/> </bean>
默认情况下,如果有配置的 applicationEventMulticaster, 按照约定的默认名称获取发布者, 如果没有 代码自动new一个 发布者。这种默认值是 很多配置框架的一个原则-- 约定优于配置。