1. 程式人生 > >spring事件監聽機制

spring事件監聽機制

ide could 事情 task object 負責 his try and

技術分享圖片

事件機制的主要成員:  

  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事件監聽機制