spring学习(六):容器事件
事件体系其实是观察者模式的一种具体实现方式 Spring的 ApplicationContext能够发布事件并允许注册相应的事件监听器,是因为他拥有一套完善的事件发布与监听机制。
一、java中的事件机制实现
通过java.util.EventObject和java.util.EventLinister接口描述事件和监听器。某个组件或框架如需事件发布和 监听机制,都需要通过拓展它们进行定义。在事件体系中,除了事件和监听器之外,还有另外三个重要的概念:
- 事件源:事件的产生者,任何一个EventObjecct(事件)都必须有一个事件源
- 事件监听器注册表:提供保存事件监听器的地方,一个事件监听器注册到组件或框架后,其实就是保存在事件监听器注册表中。当组件和框架中的事件源产生消息时,就会通知这些位于事件监听注册器中的监听器
- 事件广播器:他是事件和事件监听器之间的桥梁,负责把事件通知给事件监听器
事件源、事件监听器注册表和事件广播器这三个角色有时可以用同一对象来承担,如java.swing包中的JButton,JCheckBox等。
二、spring的事件类结构
结构图如下所示:
ApplicationEvent的唯一构造函数是ApplicationEvent(Object source),通过source指定事件源,它有两个子类
- ApplicationContextEvent:容器事件,它拥有四个子类,分别表示容器启动,刷新,停止和关闭的事件
- RequestHandleEvent:这是一个与web应用相关的事件,当一个HTTP请求被处理后,产生该事件。只有在web.xml中定义了DispatcherServlet时才会产生该事件。它拥有两个子类,分别代表servlet及portlet请求事件
三、事件监听器结构
spring的事件监听器都继承自ApplicationListener,结构如下:
ApplicationListener只定义了一个方法,onApplicationEvent(E event),该方法接受ApplicationEvent对象,在该方法中编辑事件响应的逻辑
四、事件广播器
另外的,事件广播器要拥有发布事件的能力,就必须实现ApplicationContextAware接口
五、解构spring事件体系的具体实现
Spring在ApplicationContext接口的抽象实现类AbstractApplicationContext中完成事件体系的搭建。在refresh()方法中通过三个步骤搭建了事件的基础设施
- 首先在5处,Spring初始化事件广播器,只要实现ApplicationEventMulticaster即可,spring通过反射机制将其注册成事件广播器,如果没有找到配置的自定义事件广播器,spring会使用默认的SimpleApplicationEventMulticaster作为事件广播器
- 在7处,Spring根据反射机制从BeanDefinitionRegistry中找到所有实现了ApplicationListener的bean,将他们注册为容器的事件监听器,即添加到事件广播器提供的事件监听器注册表中
- 在9处,容器启动完成,调用事件发布接口向容器中所有的监听器发送事件,在publishEvent()方法中可以看到,Spring委托ApplicationContextMulticaster将事件通知给事件监听器
至此,spring事件体系全部完成。后期会附一个实例。