事件機制

事件機制spring

相關概念:
	事件EventObject
	事件生成器 				事件的產生者,生成事件後,使用事件發佈器發佈事件。
	事件生成器工廠 			生產多種類型的事件生成器
	事件發佈器EventPublisher 	發佈事件:將事件發佈到廣播器中。
	事件廣播器 				通知在事件監聽器註冊表中註冊的事件監聽器。即將事件dispatch到對應的監聽器上。
	事件監聽器EventListener 	監聽事件,並作相應的處理。
	事件監聽器註冊表 			管理事件監聽器,廣播器經過註冊表來尋找指定的監聽器。

執行流程:
	1)初始化監聽器註冊表。
	2)businessService ---> 生成事件 ---> 發佈事件 ---> 廣播器:從註冊表中獲取指定類型的監聽器,並通知監聽器 ---> 各個監聽器響應該事件。

jdk的事件機制:數據結構

事件:EventObject
未定義事件發佈器
事件監聽器:EventListener

spring的事件機制:app

事件:ApplicationEvent
	繼承了jdk的EventObject

事件生成器:spring中並無定義事件生成器,spring直接經過new ApplicationEvent的實現類來生成事件。

事件發佈器:ApplicationEventPublisher
	實現:
		ApplicationContext繼承了ApplicationEventPublisher,即ApplicationContext的實現類做爲不一樣的事件發佈器。
		將事件發佈到廣播器中:AbstractApplicationContext調用廣播器的multicastEvent()方法將事件發佈到廣播器中。

事件廣播器:ApplicationEventMulticaster
	實現:
		默認廣播器:SimpleApplicationEventMulticaster
		使用multicastEvent()方法來廣播事件:
			從註冊表中獲取監聽器:使用getApplicationListeners()方法從註冊表中獲取事件監聽器。
			通知監聽器:使用invokeListener()方法來通知指定的監聽器,invokeListener()方法內調用了監聽器的onApplicationEvent方法。

事件監聽器:ApplicationListener
	繼承了jdk的EventListener

事件監聽器註冊表:
	實現:
		數據結構:AbstractApplicationContext的applicationListeners屬性:
			private final Set<ApplicationListener<?>> applicationListeners = new LinkedHashSet<ApplicationListener<?>>();
		註冊監聽器:經過AbstractApplicationContext的addApplicationListener()方法將監聽器添加到註冊表中。
		初始化:容器啓動的時候,會初始化註冊表。
			eg:在建立容器和初始化容器時會調用FrameworkServlet.configureAndRefreshWebApplicationContext()方法,該方法會調用addApplicationListener()方法來註冊監聽器。

說明:

	
    /**
     * ApplicationContext(更確切的說是AbstractApplicationContext)在spring的事件機制中扮演了多個角色:事件發佈器、事件廣播器、監聽器註冊表
     */
	public abstract class AbstractApplicationContext implements ApplicationContext {

		// ApplicationContext繼承了ApplicationEventPublisher,故AbstractApplicationContext即事件發佈器

		// 事件廣播器 
		/** Helper class used in event publishing */
		private ApplicationEventMulticaster applicationEventMulticaster;

		// 事件監聽器註冊表
		private final Set<ApplicationListener<?>> applicationListeners = new LinkedHashSet<ApplicationListener<?>>();

		/** ApplicationEvents published early */
		private Set<ApplicationEvent> earlyApplicationEvents;


		@Override
		public void addApplicationListener(ApplicationListener<?> listener) {
			if (this.applicationEventMulticaster != null) {
				this.applicationEventMulticaster.addApplicationListener(listener);
			}
			else {
				this.applicationListeners.add(listener);
			}
		}


		// 發佈事件
		@Override
		public void publishEvent(ApplicationEvent event) {
			publishEvent(event, null);
		}

		protected void publishEvent(Object event, ResolvableType eventType) {

			// Decorate event as an ApplicationEvent if necessary
			ApplicationEvent applicationEvent;
			if (event instanceof ApplicationEvent) {
				applicationEvent = (ApplicationEvent) event;
			} else {
				applicationEvent = new PayloadApplicationEvent<Object>(this, event);
				if (eventType == null) {
					eventType = ((PayloadApplicationEvent)applicationEvent).getResolvableType();
				}
			}

			// Multicast right now if possible - or lazily once the multicaster is initialized
			if (this.earlyApplicationEvents != null) {
				this.earlyApplicationEvents.add(applicationEvent);
			} else {
				getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);
			}

			// Publish event via parent context as well...
			if (this.parent != null) {
				if (this.parent instanceof AbstractApplicationContext) {
					((AbstractApplicationContext) this.parent).publishEvent(event, eventType);
				} else {
					this.parent.publishEvent(event);
				}
			}
		}

	}


舉例:
duboo服務的導出:
	監聽器:ServiceBean
			ServiceBean實現了spring的ApplicationListener接口,而且監聽着spring的上下文刷新事件(ContextRefreshedEvent),當監聽到spring的上下文刷新事件時,執行服務導出操做。
相關文章
相關標籤/搜索