一,jdk 事件对象基类
package java.util; import java.io.Serializable; public class EventObject
implements Serializable
{
protected transient Object source; public Object getSource()
{
return this.source;
} public EventObject(Object paramObject)
{
if (paramObject == null)
throw new IllegalArgumentException("null source");
this.source = paramObject;
} public String toString()
{
return getClass().getName() + "[source=" + this.source + "]";
}
}
2。spring事件基类
public abstract class ApplicationEvent extends EventObject { /** use serialVersionUID from Spring 1.2 for interoperability */
private static final long serialVersionUID = 7099057708183571937L; /** System time when the event happened */
private final long timestamp; /**
* Create a new ApplicationEvent.
* @param source the component that published the event (never <code>null</code>)
*/
public ApplicationEvent(Object source) {
super(source);
this.timestamp = System.currentTimeMillis();
} /**
* Return the system time in milliseconds when the event happened.
*/
public final long getTimestamp() {
return this.timestamp;
} }
3,ApplicationContextEvent基类
public abstract class ApplicationContextEvent extends ApplicationEvent { /**
* Create a new ContextStartedEvent.
* @param source the <code>ApplicationContext</code> that the event is raised for
* (must not be <code>null</code>)
*/
public ApplicationContextEvent(ApplicationContext source) {
super(source);
} /**
* Get the <code>ApplicationContext</code> that the event was raised for.
*/
public final ApplicationContext getApplicationContext() {
return (ApplicationContext) getSource();
} }
4。容器关闭事件
public class ContextClosedEvent extends ApplicationContextEvent { /**
* Creates a new ContextClosedEvent.
* @param source the <code>ApplicationContext</code> that has been closed
* (must not be <code>null</code>)
*/
public ContextClosedEvent(ApplicationContext source) {
super(source);
} }
5,AbstractApplicationContext中fireclose事件 public void publishEvent(ApplicationEvent event) {
Assert.notNull(event, "Event must not be null");
if (logger.isTraceEnabled()) {
logger.trace("Publishing event in " + getDisplayName() + ": " + event);
}
getApplicationEventMulticaster().multicastEvent(event);
if (this.parent != null) {
this.parent.publishEvent(event);
}
} 6,事件处理监听器控制器(SimpleApplicationEventMulticaster)
@SuppressWarnings("unchecked")
public void multicastEvent(final ApplicationEvent event) {
for (final ApplicationListener listener : getApplicationListeners(event)) {
Executor executor = getTaskExecutor();
if (executor != null) {
executor.execute(new Runnable() {
@SuppressWarnings("unchecked")
public void run() {
listener.onApplicationEvent(event);
}
});
}
else {
listener.onApplicationEvent(event);
}
}
}
7。AbstractApplicationEventMulticaster获取注冊close事件的监听器
protected Collection<applicationlistener> getApplicationListeners(ApplicationEvent event) {
Class<? extends ApplicationEvent> eventType = event.getClass();
Class sourceType = event.getSource().getClass();
ListenerCacheKey cacheKey = new ListenerCacheKey(eventType, sourceType);
ListenerRetriever retriever = this.retrieverCache.get(cacheKey);
if (retriever != null) {
return retriever.getApplicationListeners();
}
else {
retriever = new ListenerRetriever(true);
LinkedList<applicationlistener> allListeners = new LinkedList<applicationlistener>();
synchronized (this.defaultRetriever) {
for (ApplicationListener listener : this.defaultRetriever.applicationListeners) {
if (supportsEvent(listener, eventType, sourceType)) {
retriever.applicationListeners.add(listener);
allListeners.add(listener);
}
}
if (!this.defaultRetriever.applicationListenerBeans.isEmpty()) {
BeanFactory beanFactory = getBeanFactory();
for (String listenerBeanName : this.defaultRetriever.applicationListenerBeans) {
ApplicationListener listener = beanFactory.getBean(listenerBeanName, ApplicationListener.class);
if (!allListeners.contains(listener) && supportsEvent(listener, eventType, sourceType)) {
retriever.applicationListenerBeans.add(listenerBeanName);
allListeners.add(listener);
}
}
}
OrderComparator.sort(allListeners);
this.retrieverCache.put(cacheKey, retriever);
}
return allListeners;
}
} 二,
1,监听器基类
public interface EventListener
{
}
2,spring监听器基类
public interface ApplicationListener<e extends="" applicationevent=""> extends EventListener { /**
* Handle an application event.
* @param event the event to respond to
*/
void onApplicationEvent(E event); }
3。AbstractApplicationContext加入监听
public void addApplicationListener(ApplicationListener<?> listener) {
if (this.applicationEventMulticaster != null) {
this.applicationEventMulticaster.addApplicationListener(listener);
}
else {
this.applicationListeners.add(listener);
}
}
4,加入listenner到AbstractApplicationEventMulticaster
public void addApplicationListener(ApplicationListener listener) {
synchronized (this.defaultRetriever) {
this.defaultRetriever.applicationListeners.add(listener);
this.retrieverCache.clear();
}
}
5,监听处理类注冊入口AbstractApplicationContext
public Object postProcessAfterInitialization(Object bean, String beanName) {
if (bean instanceof ApplicationListener) {
// potentially not detected as a listener by getBeanNamesForType retrieval
Boolean flag = this.singletonNames.get(beanName);
if (Boolean.TRUE.equals(flag)) {
// singleton bean (top-level or inner): register on the fly
addApplicationListener((ApplicationListener<?>) bean);
}
else if (flag == null) {
if (logger.isWarnEnabled() && !containsBean(beanName)) {
// inner bean with other scope - can't reliably process events
logger.warn("Inner bean '" + beanName + "' implements ApplicationListener interface " +
"but is not reachable for event multicasting by its containing ApplicationContext " +
"because it does not have singleton scope. Only top-level listener beans are allowed " +
"to be of non-singleton scope.");
}
this.singletonNames.put(beanName, Boolean.FALSE);
}
}
return bean;
} </e></applicationlistener></applicationlistener></applicationlistener>

spring 事件模式 源代码导读的更多相关文章

  1. Spring 事件监听机制及原理分析

    简介 在JAVA体系中,有支持实现事件监听机制,在Spring 中也专门提供了一套事件机制的接口,方便我们实现.比如我们可以实现当用户注册后,给他发送一封邮件告诉他注册成功的一些信息,比如用户订阅的主 ...

  2. spring发布和接收定制的事件(spring事件传播)

    spring发布和接收定制的事件(spring事件传播) 2012-12-26 20:05 22111人阅读 评论(2) 收藏 举报  分类: 开源技术(如Struts/spring/Hibernat ...

  3. 【转载】详细解读C#中的 .NET 弱事件模式

    你可能知道,事件处理是内存泄漏的一个常见来源,它由不再使用的对象存留产生,你也许认为它们应该已经被回收了,但不是,并有充分的理由. 在这个短文中(期望如此),我会在 .Net 框架的上下文事件处理中展 ...

  4. C#中的 .NET 弱事件模式

    引言 你可能知道,事件处理是内存泄漏的一个常见来源,它由不再使用的对象存留产生,你也许认为它们应该已经被回收了,但不是,并有充分的理由. 在这个短文中(期望如此),我会在 .Net 框架的上下文事件处 ...

  5. spring 事件(Application Event)

    spring 事件为bean 与 bean之间传递消息.一个bean处理完了希望其余一个接着处理.这时我们就需要其余的一个bean监听当前bean所发送的事件. spring事件使用步骤如下: 1.先 ...

  6. C#代码:用事件模式实现通知

    事件提供了一种标准的机制来通知监听者..NET的事件模式使用了事件语法来实现观察者模式.任意数量的客户对象都可以将自己的处理函数注册到事件上,然后处理这些事件.这些客户对象不需要再编译期就给出.时间也 ...

  7. Spring mvc 模式小结

    http://www.taobaotesting.com/blogs/2375 1.spring mvc简介 Spring MVC框架是一个MVC框架,通过实现Model-View-Controlle ...

  8. Qt中事件分发源代码剖析(一共8个步骤,顺序非常清楚:全局的事件过滤器,再传递给目标对象的事件过滤器,最终传递给目标对象)

    Qt中事件分发源代码剖析 Qt中事件传递顺序: 在一个应该程序中,会进入一个事件循环,接受系统产生的事件,并且进行分发,这些都是在exec中进行的.下面举例说明: 1)首先看看下面一段示例代码: in ...

  9. Spring事件解析

    首先介绍Spring事件相关类的关系: 其中EventListener与EventObject均是Java SE的范畴,源码如下: package java.util; public interfac ...

随机推荐

  1. 多线程并发情况下 重复insert问题

    代码逻辑: if(数据不存在){ insert(); } 线程启动后,发现数据库表中有相同的记录 解决方案 synchronized同步代码块即加同步锁,synchronized同步代码块的功能: 当 ...

  2. 【MySQL】浅谈 varchar(N)

    一  前言  varchar(N) N代表什么意思,能存放多少个中文字符?属于老生常谈的问题了,今天又被一个开发同事问我关于这个问题,索性写一篇文章来具体介绍一下.二 理论知识 先说明一下 MySQL ...

  3. 算法学习记录-图——最小生成树之Kruskal算法

    之前的Prim算法是基于顶点查找的算法,而Kruskal则是从边入手. 通俗的讲:就是希望通过 边的权值大小 来寻找最小生成树.(所有的边称为边集合,最小生成树形成的过程中的顶点集合称为W) 选取边集 ...

  4. python基础学习笔记——初识函数

    什么是函数 我们目前为止,已经可以完成一些软件的基本功能了,那么我们来完成这样一个功能:约x 1 2 3 4 5 pint("拿出手机") print("打开陌陌&quo ...

  5. 18,OS模块

    import os print(os.getcwd())#执行所在的目录 # os.makedirs('\python作业\景s12\day18')#可生成多层递归目录 # os.mkdir('\py ...

  6. Hive中文注释乱码解决方案(2)

    本文来自网易云社区 作者:王潘安 执行阶段 launchTask    回到Driver类的runInternal方法,看以下执行过程.在runInternal方法中,执行过程调用了execute方法 ...

  7. mysql 基本查询

    查询不重复的记录.有时需要将表中的记录去掉重复后显示出来,可以用 distinct 关键字来实现:mysql> select ename,hiredate,sal,deptno from emp ...

  8. Sequence Models

    Sequence Models This is the fifth and final course of the deep learning specialization at Coursera w ...

  9. 此坑待填 离散化思想和凸包 UVA - 10173 Smallest Bounding Rectangle

    Smallest Bounding Rectangle Given the Cartesian coordinates of n(>0)2-dimensional points, write a ...

  10. 九度oj 题目1385:重建二叉树

    题目描述: 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7 ...