Spring 事件监听源码分析

Spring事件监听源码分析

我们接着分析refresh()方法中的事件监听的源码部分。

	@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);
				
				//BeanDefinitionRegistry和BeanFactoryPostProcessor接口看过了
				// Invoke factory processors registered as beans in the context.
				invokeBeanFactoryPostProcessors(beanFactory);

				//BeanPostProcessor接口看过了
				// 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.
				finishRefresh();
			}

			catch (BeansException ex) {
				if (logger.isWarnEnabled()) {
					logger.warn("Exception encountered during context initialization - " +
							"cancelling refresh attempt: " + ex);
				}

				// Destroy already created singletons to avoid dangling resources.
				destroyBeans();

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

				// Propagate exception to caller.
				throw ex;
			}

			finally {
				// Reset common introspection caches in Spring's core, since we
				// might not ever need metadata for singleton beans anymore...
				resetCommonCaches();
			}
		}
	}
	protected void initApplicationEventMulticaster() {
		ConfigurableListableBeanFactory beanFactory = getBeanFactory();
		//如果自己在beanFactory中注册了多播器,用自己的
		if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
			this.applicationEventMulticaster =
					beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
			if (logger.isTraceEnabled()) {
				logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
			}
		}
		else {
			//默认用SimpleApplicationEventMulticaster类型的多播器
			this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
			//这个方法看一看,这里注册的bean,是没有对应的beanDefinition的,要注意。
			//还有destorySingleton的方法可以移除单例bean
			//我们可以通过这两个方法随意增删单例bean
			beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
			if (logger.isTraceEnabled()) {
				logger.trace("No '" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "' bean, using " +
						"[" + this.applicationEventMulticaster.getClass().getSimpleName() + "]");
			}
		}
	}
	public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException {
		Assert.notNull(beanName, "Bean name must not be null");
		Assert.notNull(singletonObject, "Singleton object must not be null");
		synchronized (this.singletonObjects) {
			//不能注册同名的bean
			Object oldObject = this.singletonObjects.get(beanName);
			if (oldObject != null) {
				throw new IllegalStateException("Could not register object [" + singletonObject +
						"] under bean name '" + beanName + "': there is already object [" + oldObject + "] bound");
			}
			//看这里
			addSingleton(beanName, singletonObject);
		}
	}
	protected void addSingleton(String beanName, Object singletonObject) {
		//singletonObjects在这里放入了beanName,和bean的映射
		//singletonObjects这个就是从spring中获取单例bean的缓存集合
		//移除这两个singletonFactories,earlySingletonObjects集合中的数据
		//详细等到讲到实例化和循环依赖我们再来深究
		synchronized (this.singletonObjects) {
			this.singletonObjects.put(beanName, singletonObject);
			this.singletonFactories.remove(beanName);
			this.earlySingletonObjects.remove(beanName);
			this.registeredSingletons.add(beanName);
		}
	}
	protected void registerListeners() {
		// Register statically specified listeners first.
		//获取到applicationContext中applicationListeners
		//是一个Set<ApplicationListener<?>>集合
		//可以通过applicationContext的addApplicationListener方法添加监听器
		//注意调用时序,在refresh方法执行完以后在通过此种方法添加的,是没用的,该方法已经执行完了。
		//多播器中就没有这个监听器了,就没法广播给它了
		for (ApplicationListener<?> listener : getApplicationListeners()) {
			//向多播器内部类ListenerRetriever的applicationListeners添加监听者
			getApplicationEventMulticaster().addApplicationListener(listener);
		}

		// Do not initialize FactoryBeans here: We need to leave all regular beans
		// uninitialized to let post-processors apply to them!
		// 收集实现了ApplicationListener接口的被扫描的的beanName。
		String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
		for (String listenerBeanName : listenerBeanNames) {
			//向多播器内部类ListenerRetriever的applicationListenerBeans添加监听者
			getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
		}
			
		// Publish early application events now that we finally have a multicaster...
		//这个是在registerListeners方法执行以前
		//也就是多播器还没实例化或者
		//监听者还未加入ApplicationListener或者ApplicationListenerBean集合中
		//提前调用了applicationContext的publishEvent方法发布了的事件会暂存earlyApplicationEvents集合中
		//直到这里我们再来发布这个集合中事件,然后该集合置为空
		Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
		this.earlyApplicationEvents = null;
		if (!CollectionUtils.isEmpty(earlyEventsToProcess)) {
			for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
				//事件发布
				getApplicationEventMulticaster().multicastEvent(earlyEvent);
			}
		}
	}

    再来看事件发布的代码,也就是AbstractApplicationContext的publishEvent方法

	protected void publishEvent(Object event, @Nullable ResolvableType eventType) {
		Assert.notNull(event, "Event must not be null");

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

		// Multicast right now if possible - or lazily once the multicaster is initialized
		//prepareRefresh方法会把earlyApplicationEvents = new LinkedHashSet<>();
		//直到registerListeners方法调用之前,该集合都不为空
		//也就是在多播器和监听器全都准备完毕之前,发布的事件都暂存在这个集合中
		if (this.earlyApplicationEvents != null) {
			this.earlyApplicationEvents.add(applicationEvent);
		}
		//registerListeners方法调用之后,earlyApplicationEvents  = null
		//再发布的事件直接走这里发布了
		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);
			}
		}
	}
	public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
		ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
		//获取多播器中的taskExecutor对象,如果不为空,异步执行监听者的代码
		//可以使用多播器的setTaskExecutor方法设置Executor
		Executor executor = getTaskExecutor();
		//获取到全部的监听者,循环调用监听者的具体逻辑
		for (ApplicationListener<?> listener : getApplicationListeners(event, type)) {
			if (executor != null) {
				executor.execute(() -> invokeListener(listener, event));
			}
			else {
				invokeListener(listener, event);
			}
		}
	}
	private class ListenerRetriever {

		//applicationListeners的值在ApplicationListenerDetector类中会添加监听者
		//什么时候调用到ApplicationListenerDetector这个类的呢,等到讲到实例化bean的时候顺带提一下
		public final Set<ApplicationListener<?>> applicationListeners = new LinkedHashSet<>();

		public final Set<String> applicationListenerBeans = new LinkedHashSet<>();

		private final boolean preFiltered;

		public ListenerRetriever(boolean preFiltered) {
			this.preFiltered = preFiltered;
		}
		
		public Collection<ApplicationListener<?>> getApplicationListeners() {
			List<ApplicationListener<?>> allListeners = new ArrayList<>(
					this.applicationListeners.size() + this.applicationListenerBeans.size());
			//先添加applicationListeners的监听者
			allListeners.addAll(this.applicationListeners);
			if (!this.applicationListenerBeans.isEmpty()) {
				BeanFactory beanFactory = getBeanFactory();
				for (String listenerBeanName : this.applicationListenerBeans) {
					try {	
						//beanFactory.getBean触发了我们监听者Bean的实例化
						//如果是单例后续直接从singletonObjects集合中获取到对象
						//beanFactory.getBean后面讲解实例化再详细说明
						ApplicationListener<?> listener = beanFactory.getBean(listenerBeanName, ApplicationListener.class);
						//如果applicationListeners没有再添加,防止重复通知监听者
						if (this.preFiltered || !allListeners.contains(listener)) {
							//添加监听者
							allListeners.add(listener);
						}
					}
					catch (NoSuchBeanDefinitionException ex) {
						// Singleton listener instance (without backing bean definition) disappeared -
						// probably in the middle of the destruction phase
					}
				}
			}
			if (!this.preFiltered || !this.applicationListenerBeans.isEmpty()) {
				//对所有监听者排序
				//AnnotationAwareOrderComparator继承OrderComparator实现了Comparator接口
				//优先级 实现了PriorityOrdered接口的 > 实现Orderd接口的和@Order注解 > 啥都没有的
				AnnotationAwareOrderComparator.sort(allListeners);
			}
			return allListeners;
		}
	}
	protected void invokeListener(ApplicationListener<?> listener, ApplicationEvent event) {
		//和设置Executor一样,也可以设置ErrorHandler用于处理监听者执行异常的情况
		ErrorHandler errorHandler = getErrorHandler();
		if (errorHandler != null) {
			try {
				doInvokeListener(listener, event);
			}
			catch (Throwable err) {
				errorHandler.handleError(err);
			}
		}
		else {
			//看这里
			doInvokeListener(listener, event);
		}
	}
	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())) {
				// 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.isTraceEnabled()) {
					logger.trace("Non-matching event type for listener: " + listener, ex);
				}
			}
			else {
				throw ex;
			}
		}
	}

到此,事件监听的相关代码就结束了。最后,举个简单的使用例子。

public class MyTest {

    @Test
    public void test1(){
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
        //source可以传业务相关的对象
        applicationContext.publishEvent(new MyEvent("hello event","source"));
    }
}
public class MyEvent extends ApplicationEvent {

    private String name;

    public MyEvent(String name,Object source) {
        super(source);
        this.name = name;
    }
}
@Component
public class MyEventListener implements ApplicationListener<MyEvent> {

    @Override
    public void onApplicationEvent(MyEvent event) {
       
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值