栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Spring源码(五)Spring 事件监听器的两种注册方式

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Spring源码(五)Spring 事件监听器的两种注册方式

了解专栏完整的内容,请点击跳转:
Spring framework专栏导航页

gitee注释版源码


作为一款优先的框架,怎么能少得了监听器呢?虽然说现基于web开发的项目很少用到监听器(大多使用消息队列),但是有些时候又需要用到。以及我们想监听Spring容器的初始化相关事件时候,就可以用到Spring自带的的监听器实现方式。

重要组件:事件多播器

监听器思维导图


两种监听器实现方式 接口方式
@Lazy
@Component
public class ContextRefreshedInterfaceListener implements ApplicationListener {

	@Override
	public void onApplicationEvent(ContextRefreshedEvent event) {
		System.out.println("接口监听");
	}
}
注解方式
@Lazy // 加了懒加载 这个Bean不会被创建 但是 里边用注解标记的监听事件会被通过后置处理器创建出来
@Component
public class ContextRefreshedAnnotationListener {

	@EventListener(ContextRefreshedEvent.class)
	public void onAppllicationEvent(ContextRefreshedEvent event) {
		System.out.println("注解监听");
	}

}

创建多播器
// refresh().initApplicationEventMulticaster();
protected void initApplicationEventMulticaster() {
		ConfigurableListableBeanFactory beanFactory = getBeanFactory();
		//判断容器中是没有有我们的applicationEventMulticaster 应用多播器组件
		if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
			//直接显示的调用我们的getBean获取出来赋值给我们的applicationContext对象
			this.applicationEventMulticaster =
					beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
			if (logger.isTraceEnabled()) {
				logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
			}
		}
		else {
			//spring ioc显示的new 一个SimpleApplicationEventMulticaster对象保存在applicatoinContext对象中
			this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
			//并且注入到容器中
			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() + "]");
			}
		}
	}

注册接口方式监听器的后置处理器
// refresh().prepareBeanFactory(ConfigurableListableBeanFactory beanFactory);

......

// 用于处理实现了ApplicationListener接口的bean,bean初始化后将其添加到监听器集合中 来监听事件
// Register early post-processor for detecting inner beans as ApplicationListeners.
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

......

注册监听器BeanName

// 注册接口方式的监听器 其实只是注册监听器名字
// 防止懒加载监听器漏掉
// 事件发布时候 会再根据这里注册的名字 把懒加载的bean进行实例化 然后再发布事件

// refresh().registerListeners();
protected void registerListeners() {
		// 获取容器中所有的监听器对象
		// 这个时候正常流程是不会有监听器的
		// Register statically specified listeners first.
		for (ApplicationListener listener : getApplicationListeners()) {
			getApplicationEventMulticaster().addApplicationListener(listener);
		}

		//获取bean定义中的监听器对象
		// Do not initialize FactoryBeans here: We need to leave all regular beans
		// uninitialized to let post-processors apply to them!
		String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
		for (String listenerBeanName : listenerBeanNames) {
			// 把监听器名字注册进多播器中
			getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
		}

		//在这里获取我们的早期事件
		// Publish early application events now that we finally have a multicaster...
		Set earlyEventsToProcess = this.earlyApplicationEvents;
		// 在这里赋null。  也就是值此之后都将没有早期事件了
		this.earlyApplicationEvents = null;
		if (!CollectionUtils.isEmpty(earlyEventsToProcess)) {
			//通过多播器进行播发早期事件
			for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
				getApplicationEventMulticaster().multicastEvent(earlyEvent);
			}
		}
	}

Bean初始化后注册接口方式监听器到多播器中

@Override
	public Object postProcessAfterInitialization(Object bean, String beanName) {
		if (bean instanceof ApplicationListener) {
			// potentially not detected as a listener by getBeanNamesForType retrieval
			Boolean flag = this.singletonNames.get(beanName);
			if (Boolean.TRUE.equals(flag)) {
				// singleton bean (top-level or inner): register on the fly
				this.applicationContext.addApplicationListener((ApplicationListener) bean);
			}
			else if (Boolean.FALSE.equals(flag)) {
				if (logger.isWarnEnabled() && !this.applicationContext.containsBean(beanName)) {
					// inner bean with other scope - can't reliably process events
					logger.warn("Inner bean '" + beanName + "' implements ApplicationListener interface " +
							"but is not reachable for event multicasting by its containing ApplicationContext " +
							"because it does not have singleton scope. only top-level listener beans are allowed " +
							"to be of non-singleton scope.");
				}
				this.singletonNames.remove(beanName);
			}
		}
		return bean;
	}

所有Bean创建完成后注册注解方式监听器
// DefaultListableBeanFactory#preInstantiateSingletons
// 所有bean都创建完了 可以实现SmartInitializingSingleton来做扩展
// 解析注解方式监听器就是在这里进行的
// Trigger post-initialization callback for all applicable beans...
		for (String beanName : beanNames) {
			Object singletonInstance = getSingleton(beanName);
			if (singletonInstance instanceof SmartInitializingSingleton) {
				StartupStep smartInitialize = this.getApplicationStartup().start("spring.beans.smart-initialize")
						.tag("beanName", beanName);
				SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
				if (System.getSecurityManager() != null) {
					AccessController.doPrivileged((PrivilegedAction) () -> {
						smartSingleton.afterSingletonsInstantiated();
						return null;
					}, getAccessControlContext());
				}
				else {
					smartSingleton.afterSingletonsInstantiated();
				}
				smartInitialize.end();
			}
		}
 
@Override
	public void afterSingletonsInstantiated() {
		ConfigurableListableBeanFactory beanFactory = this.beanFactory;
		Assert.state(this.beanFactory != null, "No ConfigurableListableBeanFactory set");
		String[] beanNames = beanFactory.getBeanNamesForType(Object.class);
		for (String beanName : beanNames) {
			if (!ScopedProxyUtils.isScopedTarget(beanName)) {
				Class type = null;
				try {
					type = AutoProxyUtils.determineTargetClass(beanFactory, beanName);
				}
				catch (Throwable ex) {
					// An unresolvable bean type, probably from a lazy bean - let's ignore it.
					if (logger.isDebugEnabled()) {
						logger.debug("Could not resolve target class for bean with name '" + beanName + "'", ex);
					}
				}
				if (type != null) {
					if (ScopedObject.class.isAssignableFrom(type)) {
						try {
							Class targetClass = AutoProxyUtils.determineTargetClass(
									beanFactory, ScopedProxyUtils.getTargetBeanName(beanName));
							if (targetClass != null) {
								type = targetClass;
							}
						}
						catch (Throwable ex) {
							// An invalid scoped proxy arrangement - let's ignore it.
							if (logger.isDebugEnabled()) {
								logger.debug("Could not resolve target bean for scoped proxy '" + beanName + "'", ex);
							}
						}
					}
					try {
						// 开始创建事件监听器
						processBean(beanName, type);
					}
					catch (Throwable ex) {
						throw new BeanInitializationException("Failed to process @EventListener " +
								"annotation on bean with name '" + beanName + "'", ex);
					}
				}
			}
		}
	}
private void processBean(final String beanName, final Class targetType) {
		if (!this.nonAnnotatedClasses.contains(targetType) &&
				AnnotationUtils.isCandidateClass(targetType, EventListener.class) &&
				!isSpringContainerClass(targetType)) {

			Map annotatedMethods = null;
			try {
				annotatedMethods = MethodIntrospector.selectMethods(targetType,
						(MethodIntrospector.metadataLookup) method ->
								AnnotatedElementUtils.findMergedAnnotation(method, EventListener.class));
			}
			catch (Throwable ex) {
				// An unresolvable type in a method signature, probably from a lazy bean - let's ignore it.
				if (logger.isDebugEnabled()) {
					logger.debug("Could not resolve methods for bean with name '" + beanName + "'", ex);
				}
			}

			if (CollectionUtils.isEmpty(annotatedMethods)) {
				this.nonAnnotatedClasses.add(targetType);
				if (logger.isTraceEnabled()) {
					logger.trace("No @EventListener annotations found on bean class: " + targetType.getName());
				}
			}
			else {
				// Non-empty set of methods
				ConfigurableApplicationContext context = this.applicationContext;
				Assert.state(context != null, "No ApplicationContext set");
				// 这个监听器工厂在注册内置后置处理器时候注册了bean定义 然后由EventListenerMethodProcessor将其放进集合中
				// EventListenerMethodProcessor实现了多个接口 有多个功能
				List factories = this.eventListenerFactories;
				Assert.state(factories != null, "EventListenerFactory List not initialized");
				for (Method method : annotatedMethods.keySet()) {
					for (EventListenerFactory factory : factories) {
						if (factory.supportsMethod(method)) {
							Method methodToUse = AopUtils.selectInvocableMethod(method, context.getType(beanName));
							// 创建事件监听器
							ApplicationListener applicationListener =
									factory.createApplicationListener(beanName, targetType, methodToUse);
							if (applicationListener instanceof ApplicationListenerMethodAdapter) {
								((ApplicationListenerMethodAdapter) applicationListener).init(context, this.evaluator);
							}
							// 注册事件到Context中
							context.addApplicationListener(applicationListener);
							break;
						}
					}
				}
				if (logger.isDebugEnabled()) {
					logger.debug(annotatedMethods.size() + " @EventListener methods processed on bean '" +
							beanName + "': " + annotatedMethods);
				}
			}
		}
	}

发布事件
// refresh().finishRefresh().publishEvent(new ContextRefreshedEvent(this));
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();
			}
		}

		// 这里是唯一添加早期事件的地方。所以一定要发布事件才能添加早期事件
		// 只有当执行refresh-->registerListeners 才会将earlyApplicationEvents赋为null
		// 所以registerListeners之前发布的事件都是早期事件
		// 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);
			}
		}
	}
@Override
	public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
		ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
		Executor executor = getTaskExecutor();
		//从多播器中获取出所有的监听器
		// 如果是懒加载的接口方式监听器 会在这里获取监听器时候进行创建
		for (ApplicationListener listener : getApplicationListeners(event, type)) {
			//判断多播器中是否支持异步多播的
			if (executor != null) {
				executor.execute(() -> invokeListener(listener, event));
			}
			else {
				//同步播发
				invokeListener(listener, event);
			}
		}
	}
转载请注明:文章转载自 www.mshxw.com
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号