Springboot内置ApplicationListener--DelegatingApplicationListener

本文深入剖析了SpringBoot中DelegatingApplicationListener类的工作原理,该类负责监听并广播环境属性context.listener.classes指定的事件监听器。当接收到特定事件如ApplicationEnvironmentPreparedEvent时,会初始化并注册这些监听器,随后将所有应用事件广播给它们。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

源码分析

本文源代码基于 Springboot 2.1.0

package org.springframework.boot.context.config;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.springframework.beans.BeanUtils;
import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent;
import org.springframework.context.ApplicationContextException;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.SimpleApplicationEventMulticaster;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;

/**
 * ApplicationListener that delegates to other listeners that are specified under
 * a context.listener.classes environment property.
 *  
 * 监听应用事件,并将这些应用事件广播给环境属性context.listener.classes指定的那些监听器。
 * 
 * @author Dave Syer
 * @author Phillip Webb
 */
public class DelegatingApplicationListener
		implements ApplicationListener<ApplicationEvent>, Ordered {

	// NOTE: Similar to org.springframework.web.context.ContextLoader

	private static final String PROPERTY_NAME = "context.listener.classes";

	private int order = 0;

	private SimpleApplicationEventMulticaster multicaster;

	@Override
	public void onApplicationEvent(ApplicationEvent event) {
		if (event instanceof ApplicationEnvironmentPreparedEvent) {
			// 听到ApplicationEnvironmentPreparedEvent事件时,尝试根据环境属性
			// context.listener.classes构造相应的事件监听器
			List<ApplicationListener<ApplicationEvent>> delegates = getListeners(
					((ApplicationEnvironmentPreparedEvent) event).getEnvironment());
			if (delegates.isEmpty()) {
				return;
			}
			// 如果环境属性context.listener.classes指定了有效的事件监听器,构造一个
			// 事件多播器,将所有这些事件监听器登记到该多播器上。
			this.multicaster = new SimpleApplicationEventMulticaster();
			for (ApplicationListener<ApplicationEvent> listener : delegates) {
				this.multicaster.addApplicationListener(listener);
			}
		}
		// 如果是ApplicationEnvironmentPreparedEvent之外的其他应用事件,将该事件
		// 直接通过事件多播器广播到环境属性context.listener.classes指定的那些事件监听器上。
		if (this.multicaster != null) {
			this.multicaster.multicastEvent(event);
		}
	}

	@SuppressWarnings("unchecked")
	private List<ApplicationListener<ApplicationEvent>> getListeners(
			ConfigurableEnvironment environment) {
		if (environment == null) {
			return Collections.emptyList();
		}
		// 获取环境属性context.listener.classes指定的事件监听器的类名称,0个或者多个,使用逗号分隔
		String classNames = environment.getProperty(PROPERTY_NAME);
		List<ApplicationListener<ApplicationEvent>> listeners = new ArrayList<>();
		if (StringUtils.hasLength(classNames)) {
			for (String className : StringUtils.commaDelimitedListToSet(classNames)) {
				// 创建每个事件监听器的一个实例
				try {
					Class<?> clazz = ClassUtils.forName(className,
							ClassUtils.getDefaultClassLoader());
					Assert.isAssignable(ApplicationListener.class, clazz, "class ["
							+ className + "] must implement ApplicationListener");
					listeners.add((ApplicationListener<ApplicationEvent>) BeanUtils
							.instantiateClass(clazz));
				}
				catch (Exception ex) {
					throw new ApplicationContextException(
							"Failed to load context listener class [" + className + "]",
							ex);
				}
			}
		}
		// 根据事件多播器上的排序注解属性对它们进行排序
		AnnotationAwareOrderComparator.sort(listeners);
		return listeners;
	}

	public void setOrder(int order) {
		this.order = order;
	}

	@Override
	public int getOrder() {
		return this.order;
	}

}

相关文章

Springboot内置ApplicationListener

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值