Spring 事件傳播機制分析

Spring4.0.4java

Spring 事件機制採用的是觀察者模型(又叫訂閱發佈模型)spring

有如下角色緩存

這裏,觀察者就是監聽者,被觀察者就是事件對象。app

事件發佈流程以下異步

下面以ClassPathXmlApplicationContext初始化完後,發佈,容器完成事件,爲例說明ide

ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("xxx.xml");

執行以上模板代碼,啓動Spring容器時,會調用post

public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
		throws BeansException {

	super(parent);
	setConfigLocations(configLocations);
	if (refresh) {
		refresh();//在父類AbstractApplicationContext中實現
	}
}

AbstractApplicationContext類方法this

@Override
public void refresh() throws BeansException, IllegalStateException {
	synchronized (this.startupShutdownMonitor) {
		// Prepare this context for refreshing.
		prepareRefresh();

		// Tell the subclass to refresh the internal bean factory.
		ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

		// Prepare the bean factory for use in this context.
		prepareBeanFactory(beanFactory);

		try {
			// Allows post-processing of the bean factory in context subclasses.
			postProcessBeanFactory(beanFactory);

			// Invoke factory processors registered as beans in the context.
			invokeBeanFactoryPostProcessors(beanFactory);

			// Register bean processors that intercept bean creation.
			registerBeanPostProcessors(beanFactory);

			// Initialize message source for this context.
			initMessageSource();

			// Initialize event multicaster for this context.初始化廣播器。廣播事件(被觀察者)用
			initApplicationEventMulticaster();

			// Initialize other special beans in specific context subclasses.
			onRefresh();

			// Check for listener beans and register them
			//註冊系統裏的監聽者(觀察者)
			registerListeners();

			// Instantiate all remaining (non-lazy-init) singletons.
			finishBeanFactoryInitialization(beanFactory);

			// Last step: publish corresponding event.
			//spring完成了容器啓動。就發了一個事件通知監聽者
			finishRefresh();
		}

		catch (BeansException ex) {
			// Destroy already created singletons to avoid dangling resources.
			destroyBeans();

			// Reset 'active' flag.
			cancelRefresh(ex);

			// Propagate exception to caller.
			throw ex;
		}
	}
}

以上即便Spring啓動流程,也是Spring模板方法模式的體現線程

// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
// Initialize other special beans in specific context subclasses.
onRefresh();//都是在子類實現的,,題外話。接着,看finishRefresh()debug

protected void finishRefresh() {
		// Initialize lifecycle processor for this context.
		initLifecycleProcessor();

		// Propagate refresh to lifecycle processor first.
		getLifecycleProcessor().onRefresh();

		// Publish the final event.//發送一個完成事件ContextRefreshedEvent
		//ContextRefreshedEvent 繼承自 ApplicationContextEvent
		//ApplicationContextEvent 繼承自 ApplicationEvent 
		//因爲AbstractApplicationContext實現了ApplicationEventPublisher接口,因此它自己就是發佈者
		publishEvent(new ContextRefreshedEvent(this));

		// Participate in LiveBeansView MBean, if active.
		LiveBeansView.registerApplicationContext(this);
	}

再看publishEvent實現

@Override
	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);//調用父類發佈方法向上傳播
		}
	}
	/**
	 * Return the internal ApplicationEventMulticaster used by the context.
	 * @return the internal ApplicationEventMulticaster (never {@code null})
	 * @throws IllegalStateException if the context has not been initialized yet
	 */
	ApplicationEventMulticaster getApplicationEventMulticaster() throws IllegalStateException {
		if (this.applicationEventMulticaster == null) {
			throw new IllegalStateException("ApplicationEventMulticaster not initialized - " +
					"call 'refresh' before multicasting events via the context: " + this);
		}
		return this.applicationEventMulticaster;//廣播器了已提早初始化好,前面refresh()方法裏調用initApplicationEventMulticaster()實現。
	}

//具體
		/**
	 * Initialize the ApplicationEventMulticaster.
	 * Uses SimpleApplicationEventMulticaster if none defined in the context.
	 * @see org.springframework.context.event.SimpleApplicationEventMulticaster
	 */
	protected void initApplicationEventMulticaster() {
		ConfigurableListableBeanFactory beanFactory = getBeanFactory();
		if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {//能夠自定義廣播器,名字要取applicationEventMulticaster
			this.applicationEventMulticaster =
					beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);//記得實現ApplicationEventMulticaster
			if (logger.isDebugEnabled()) {
				logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
			}
		}
		else {
			this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);//沒有就默認這個,Spring 自實現的,是個內部類,下面會看到它的multicastEvent(final ApplicationEvent event)方法
			beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);//註冊,廣播器是單例的。
			if (logger.isDebugEnabled()) {
				logger.debug("Unable to locate ApplicationEventMulticaster with name '" +
						APPLICATION_EVENT_MULTICASTER_BEAN_NAME +
						"': using default [" + this.applicationEventMulticaster + "]");
			}
		}
	}
//看看multicastEvent方法
	public class SimpleApplicationEventMulticaster extends AbstractApplicationEventMulticaster {

        //.....

	@Override
	@SuppressWarnings({ "unchecked", "rawtypes" })
	public void multicastEvent(final ApplicationEvent event) {
	//getApplicationListeners(event),獲取listeners 調用listener.onApplicationEvent(event);通知
	//getApplicationListeners方法在AbstractApplicationEventMulticaster類實現
		for (final ApplicationListener listener : getApplicationListeners(event)) {
			Executor executor = getTaskExecutor();
			if (executor != null) {//有線程池,還能異步執行。
				executor.execute(new Runnable() {
					@Override
					public void run() {
						listener.onApplicationEvent(event);
					}
				});
			}
			else {
				listener.onApplicationEvent(event);
			}
		}
	}

}

//AbstractApplicationEventMulticaster類中的實現

* Return a Collection of ApplicationListeners matching the given
	 * event type. Non-matching listeners get excluded early.
	 * @param event the event to be propagated. Allows for excluding
	 * non-matching listeners early, based on cached matching information.
	 * @return a Collection of ApplicationListeners
	 * @see org.springframework.context.ApplicationListener
	 */
	protected Collection<ApplicationListener<?>> getApplicationListeners(ApplicationEvent event) {
		Class<? extends ApplicationEvent> eventType = event.getClass();
		Object source = event.getSource();
		Class<?> sourceType = (source != null ? source.getClass() : null);
		ListenerCacheKey cacheKey = new ListenerCacheKey(eventType, sourceType);
		ListenerRetriever retriever = this.retrieverCache.get(cacheKey);//這裏用到了cache
		//全部的listener對象,都放在retriever裏的,
		if (retriever != null) {//有緩存,就直接返回。
			return retriever.getApplicationListeners();
		}
		else {
			retriever = new ListenerRetriever(true);
			LinkedList<ApplicationListener<?>> allListeners = new LinkedList<ApplicationListener<?>>();
			Set<ApplicationListener<?>> listeners;
			Set<String> listenerBeans;
			synchronized (this.defaultRetriever) {
			//開始疑惑this.defaultRetriever.applicationListeners從哪來,其實這個是
			//AbstractApplicationContext經過addApplicationListener方法手動加進來的,這是個public方法,爲配置監聽器提供了更大的靈活性
				listeners = new LinkedHashSet<ApplicationListener<?>>(this.defaultRetriever.applicationListeners);
				listenerBeans = new LinkedHashSet<String>(this.defaultRetriever.applicationListenerBeans);
			}
			for (ApplicationListener<?> listener : listeners) {
			         //這裏要注意下,有個驗證監聽者和事件類型匹配操做
				 //具體驗證法就是 監聽器的接收事件類型是否是與當前類型匹配,用的是Class.isAssignableFrom這個方法。
				if (supportsEvent(listener, eventType, sourceType)) {
					retriever.applicationListeners.add(listener);
					allListeners.add(listener);
				}
			}
			if (!listenerBeans.isEmpty()) {
				BeanFactory beanFactory = getBeanFactory();
				for (String listenerBeanName : listenerBeans) {
					try {
						Class<?> listenerType = beanFactory.getType(listenerBeanName);
						//驗證
						if (listenerType == null || supportsEvent(listenerType, event)) {
							ApplicationListener<?> listener =
									beanFactory.getBean(listenerBeanName, ApplicationListener.class);
							//驗證
							if (!allListeners.contains(listener) && supportsEvent(listener, eventType, sourceType)) {
								retriever.applicationListenerBeans.add(listenerBeanName);
								allListeners.add(listener);
							}
						}
					}
					catch (NoSuchBeanDefinitionException ex) {
						// Singleton listener instance (without backing bean definition) disappeared -
						// probably in the middle of the destruction phase
					}
				}
			}
			OrderComparator.sort(allListeners);
			if (this.beanClassLoader == null ||
					(ClassUtils.isCacheSafe(eventType, this.beanClassLoader) &&
							(sourceType == null || ClassUtils.isCacheSafe(sourceType, this.beanClassLoader)))) {
				this.retrieverCache.put(cacheKey, retriever);
			}
			return allListeners;
		}
	}
相關文章
相關標籤/搜索