spring源码-messageSource和监听器的初始化

这一节我们来看一下容器启动时messageSource的初始化和监听器的初始化。
这一节主要的源码分四块:

initMessageSource();
initApplicationEventMulticaster();
onRefresh();
registerListeners();

其中onRefresh方法是留给用户自定义的,所以这里主要看一下其他三个方法的源码。

initMessageSource

protected void initMessageSource() {
	ConfigurableListableBeanFactory beanFactory = getBeanFactory();
	//判断beanFactory中是否有messageSource的beanDefinition
	if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
		this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
		//如果有,且满足条件,则设置parent
		if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
			HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
			if (hms.getParentMessageSource() == null) {
				hms.setParentMessageSource(getInternalParentMessageSource());
			}
		}
		……日志
	}
	else {
		// 如果没有则初始化,并设置parent,最后注册到beanFactory中,这里的parent就是容器的parent,一般为null
		DelegatingMessageSource dms = new DelegatingMessageSource();
		dms.setParentMessageSource(getInternalParentMessageSource());
		this.messageSource = dms;
		beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
		……日志
	}
}

initApplicationEventMulticaster

protected void initApplicationEventMulticaster() {
    //判断beanFactory中是否存在applicationEventMulticaster的beanDefinition
	ConfigurableListableBeanFactory beanFactory = getBeanFactory();
	if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
		this.applicationEventMulticaster =
				beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
		……日志
	}
	else {
	    //如果没有则初始化,并注册
		this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
		beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
		……日志
	}
}

registerListeners

在分析registerListeners源码之前,我们先来回顾一下prepareRefresh中的一段源码:

if (this.earlyApplicationListeners == null) {
	this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
}
else {
	this.applicationListeners.clear();
	this.applicationListeners.addAll(this.earlyApplicationListeners);
}

this.earlyApplicationEvents = new LinkedHashSet<>();

通过上面的代码可以看出,spring容器会初始化两个set,earlyApplicationListeners和earlyApplicationEvents
下面我们来看一下registerListeners的源码:

protected void registerListeners() {
	//如果在spring容器初始化前earlyApplicationListeners中已经有Listener了,那么这里会执行
	for (ApplicationListener<?> listener : getApplicationListeners()) {
		getApplicationEventMulticaster().addApplicationListener(listener);
	}

	//检测beanDefinition中是否有ApplicationListener的子类如果有,则执行
	String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
	for (String listenerBeanName : listenerBeanNames) {
	    //applicationEventMulticaster为上一步监听器初始化的时候
		getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
	}

	//如果earlyApplicationEvents中存在已经发布的事件,则直接执行
	Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
	//在容器初始化后,earlyApplicationEvents又会变成null
	this.earlyApplicationEvents = null;
	if (earlyEventsToProcess != null) {
		for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
			getApplicationEventMulticaster().multicastEvent(earlyEvent);
		}
	}
}

上面这段代码前两步很简单,就是将定义的监听器注册到事件的广播中,但是这里有两个疑问:

  1. earlyApplicationEvents在什么情况下会有数据
  2. 在消息发布后,监听器是如何运作的
    要理解这两个问题,我们需要看一下publishEvent方法的源码:
protected void publishEvent(Object event, @Nullable ResolvableType eventType) {
	Assert.notNull(event, "Event must not be null");

	//这里会先判断一下event的类型,并最终会转换成ApplicationEvent
	ApplicationEvent applicationEvent;
	if (event instanceof ApplicationEvent) {
		applicationEvent = (ApplicationEvent) event;
	}
	else {
		applicationEvent = new PayloadApplicationEvent<>(this, event);
		if (eventType == null) {
			eventType = ((PayloadApplicationEvent<?>) applicationEvent).getResolvableType();
		}
	}

	/**
	* 查看earlyApplicationEvents是不是为空,如果是,那么直接执行事件的监听逻辑
	* 这里为空情况有两种:
	* 1. 在容器启动时prepareRefresh之前
	* 2. 在registerListeners之后,因为在这一步,会将earlyApplicationEvents置空
	if (this.earlyApplicationEvents != null) {
		this.earlyApplicationEvents.add(applicationEvent);
	}
	else {
		getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);
	}

	//让父容器也去消费该事件
	if (this.parent != null) {
		if (this.parent instanceof AbstractApplicationContext) {
			((AbstractApplicationContext) this.parent).publishEvent(event, eventType);
		}
		else {
			this.parent.publishEvent(event);
		}
	}
}

从上面的代码,我们知道了第一个问题的答案,至于第二个问题,我们进入执行监听逻辑的代码
getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType):

public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
    //解析出这个事件的ResolvableType
	ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
	Executor executor = getTaskExecutor();
	//再根据这个type获取到所有监听这个类型的event的listener(通过onApplicationEvent方法的参数去判断),并且执行
	for (ApplicationListener<?> listener : getApplicationListeners(event, type)) {
		if (executor != null) {
			executor.execute(() -> invokeListener(listener, event));
		}
		else {
			invokeListener(listener, event);
		}
	}
}
发布了81 篇原创文章 · 获赞 16 · 访问量 20万+

猜你喜欢

转载自blog.csdn.net/mazhen1991/article/details/100170826