spring事件监听机制

Posted 史贤庆

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了spring事件监听机制相关的知识,希望对你有一定的参考价值。

 

  事件机制的主要成员:  

  1. 事件
  2. 事件监听器(监听事件触发,处理一些事情)
  3. 事件源(发布事件)

javaSE 提供了一系列自定义事件的标准。

EvenObject,为javaSE提供的事件类型基类,任何自定义事件都必须继承它。

EventListener,为javaSE提供的事件监听器基类,任何自定义事件监听器都得实现。

javaSE未提供事件发布者,由各个应用程序自行实现事件发布者这一角色。

spring提供了ApplicationEventPublisher接口作为事件发布者,并且ApplicationContext接口继承了该接口,担当着事件发布者的角色。但ApplicationContext接口的具体实现各有差异。

spring提供了ApplicationEventMulticaster接口,负责管理ApplicationListener和发布ApplicationEvent。ApplicationContext接口会把事件的相关工作委托给ApplicationEventMulticaster的实现类做,

 

 

spring事件机制流程:

  • ApplicationContext发布事件 
//发布事件
context.publishEvent(event);

  实际上是由ApplicationContext的实现AbstractApplicationContext执行发布事件的行为

  • 找到事件广播器,广播事件
getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);
  • 执行SimpleApplicationEventMulticaster中的multicastEvent方法,调用事件监听器的onApplicationEvent()方法
	@Override
	public void multicastEvent(final ApplicationEvent event, ResolvableType eventType) {
		ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
		for (final ApplicationListener<?> listener : getApplicationListeners(event, type)) {
			Executor executor = getTaskExecutor();
			if (executor != null) {
				executor.execute(new Runnable() {
					@Override
					public void run() {
						invokeListener(listener, event);
					}
				});
			}
			else {
				invokeListener(listener, event);
			}
		}
	}

  

	protected void invokeListener(ApplicationListener<?> listener, ApplicationEvent event) {
		ErrorHandler errorHandler = getErrorHandler();
		if (errorHandler != null) {
			try {
				doInvokeListener(listener, event);
			}
			catch (Throwable err) {
				errorHandler.handleError(err);
			}
		}
		else {
			doInvokeListener(listener, event);
		}
	}

	@SuppressWarnings({"unchecked", "rawtypes"})
	private void doInvokeListener(ApplicationListener listener, ApplicationEvent event) {
		try {
			listener.onApplicationEvent(event);
		}
		catch (ClassCastException ex) {
			String msg = ex.getMessage();
			if (msg == null || matchesClassCastMessage(msg, event.getClass().getName())) {
				// Possibly a lambda-defined listener which we could not resolve the generic event type for
				// -> let\'s suppress the exception and just log a debug message.
				Log logger = LogFactory.getLog(getClass());
				if (logger.isDebugEnabled()) {
					logger.debug("Non-matching event type for listener: " + listener, ex);
				}
			}
			else {
				throw ex;
			}
		}
	}

  

自定义事件Demo

  • 自定义事件

    

package com.spring.event.event;

import org.springframework.context.ApplicationEvent;

import com.spring.event.bean.Notify;

/**
 * 自定义事件
 * @author sxq
 * @time 2018年8月31日 上午10:26:24
 *
 */
public class NotifyEvent extends ApplicationEvent {

	private int version;
	
	private Notify notify;
	public int getVersion() {
		return version;
	}

	public void setVersion(int version) {
		this.version = version;
	}

	/**
	 * serialVersionUID
	 */
	private static final long serialVersionUID = -6198589267233914254L;

	public NotifyEvent(Object source) {
		super(source);
		
	}
	public Notify getNotify() {
		return notify;
	}

	public void setNotify(Notify notify) {
		this.notify = notify;
	}

	public NotifyEvent(Object source,Notify notify) {
		this(source);
		this.notify = notify;
		
	}

}

  

  • 自定义监听器
package com.spring.event.listner;

import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;

import com.spring.event.event.NotifyEvent;

/**
 * 自定义监听器
 * @author sxq
 * @time 2018年8月31日 上午10:27:04
 *
 */
@Component
public class NotifyListenr implements ApplicationListener<NotifyEvent>{

	@Override
	public void onApplicationEvent(NotifyEvent event) {
		
		System.out.println(event.getNotify().toString());
		
		//监听事件后,处理后续事情
	}

}

  

  • 发布
	ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
	Notify notify = new Notify("李四",21);
	NotifyEvent event = new NotifyEvent("NotifyEvent",notify);
	event.setVersion(100);	
	//发布事件
     context.publishEvent(event);

  

以上是关于spring事件监听机制的主要内容,如果未能解决你的问题,请参考以下文章

深入理解Spring的容器内事件发布监听机制

深入理解Spring的容器内事件发布监听机制

Spring架构揭秘-事件监听机制

spring事件监听机制

下单流程解耦新方案-你知道Spring事件监听机制吗

扒去Spring事件监听机制的外衣,竟然是观察者模式