SpringBoot监听器源码解析

1.1 创建SpringApplication对象

public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {
		return new SpringApplication(primarySources).run(args);
}

SpringApplication(。。){
    //获取到所有配置的ApplicationListener类型的监听器,放到属性中
   setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
    
		setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
}


private <T> Collection<T> getSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes, Object... args) {
		ClassLoader classLoader = getClassLoader();
		// 读取配置
		Set<String> names = new LinkedHashSet<>(SpringFactoriesLoader.loadFactoryNames(type, classLoader));
    //遍历实例化
		List<T> instances = createSpringFactoriesInstances(type, parameterTypes, classLoader, args, names);
		AnnotationAwareOrderComparator.sort(instnces);
		return instances;
	}

去加载META-INF下面的spring.factories文件。

在spring-boot模块下
//共计10个
org.springframework.context.ApplicationListener=\
org.springframework.boot.ClearCachesApplicationListener,\
org.springframework.boot.builder.ParentContextCloserApplicationListener,\
org.springframework.boot.cloud.CloudFoundryVcapEnvironmentPostProcessor,\
org.springframework.boot.context.FileEncodingApplicationListener,\
org.springframework.boot.context.config.AnsiOutputApplicationListener,\
org.springframework.boot.context.config.ConfigFileApplicationListener,\
org.springframework.boot.context.config.DelegatingApplicationListener,\
org.springframework.boot.context.logging.ClasspathLoggingApplicationListener,\
org.springframework.boot.context.logging.LoggingApplicationListener,\
org.springframework.boot.liquibase.LiquibaseServiceLocatorApplicationListener

在spring-boot-autoconfigure模块下
org.springframework.context.ApplicationListener=\
org.springframework.boot.autoconfigure.BackgroundPreinitializer
//================================以上共计11个监听器===============================




//================================以上共计7个应用环境初始化器================================

在spring-boot模块下
org.springframework.context.ApplicationContextInitializer=\
org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer,\
org.springframework.boot.context.ContextIdApplicationContextInitializer,\
org.springframework.boot.context.config.DelegatingApplicationContextInitializer,\
org.springframework.boot.rsocket.context.RSocketPortInfoApplicationContextInitializer,\
org.springframework.boot.web.context.ServerPortInfoApplicationContextInitializer

在spring-boot-autoconfigure模块下
org.springframework.context.ApplicationContextInitializer=\
org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer,\
org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener

完成上面的逻辑之后,具体对象放到了SpringApplication的

private List<ApplicationContextInitializer<?>> initializers;

private List<ApplicationListener<?>> listeners;

属性中。

1.2 执行run逻辑
1.2.1 生成EventPublishingRunListener对象
public ConfigurableApplicationContext run(String... args) {
    //...省略若干
    //得到EventPublishingRunListener对象,同时将监听器复制给了多波器
    SpringApplicationRunListeners listeners = getRunListeners(args);   
}

getRunListeners 即获得EventPublishingRunListener实例对象。

org.springframework.boot.SpringApplicationRunListener=\
org.springframework.boot.context.event.EventPublishingRunListener

其中EventPublishingRunListener的构造方法

public EventPublishingRunListener(SpringApplication application, String[] args) {
		this.application = application;
		this.args = args;
		this.initialMulticaster = new SimpleApplicationEventMulticaster();
       //初始状态是11个。即SpringAPplication.listeners中保存的
		for (ApplicationListener<?> listener : application.getListeners()) {
			this.initialMulticaster.addApplicationListener(listener);
		}
	}
//完成这个操作,将监听器都放到initialMulticaster(多波器)的内部类中
//this.defaultRetriever.applicationListeners.add(listener);
1.2.2 prepareContext(…)
private void prepareContext(....) {
		//....省略代码。。。。
		applyInitializers(context); //这里应该是添加了3个
	   
       //....省略代码。。。。
		//AbstractApplicationContext.applicationListeners 共4个了
		listeners.contextLoaded(context);//CloudFoundryVcapEnvironmentPostProcessor
	}

protected void applyInitializers(ConfigurableApplicationContext context) {
    //遍历这7个
		for (ApplicationContextInitializer initializer : getInitializers()) {
			Class<?> requiredType = GenericTypeResolver.resolveTypeArgument(initializer.getClass(),
					ApplicationContextInitializer.class);
			Assert.isInstanceOf(requiredType, context, "Unable to call initializer.");
			initializer.initialize(context); // 有些初始化方法有逻辑,有些没有;RSocketPortInfoApplicationContextInitializer;ServerPortInfoApplicationContextInitializer; ConditionEvaluationReportLoggingListener 这三个加入进去
		}
}
AbstractApplicationContext.applicationListener属性中添加 ,共添加进去3//======================================
public void contextLoaded(ConfigurableApplicationContext context) {
    //开始这是初始的11个
		for (ApplicationListener<?> listener : this.application.getListeners()) {
			if (listener instanceof ApplicationContextAware) {
				((ApplicationContextAware) listener).setApplicationContext(context);
			}
            //添加进监听器。之前是3个,这里开始遍历哪11个往里添加。完成之后共计14个了
			context.addApplicationListener(listener);
		}
		this.initialMulticaster.multicastEvent(new ApplicationPreparedEvent(this.application, this.args, context));
}    
1.2.3 prepareRefresh()

到这里赋值给AbstractApplicationContext.earlyApplicationListeners。共计14个

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JEBgGoUl-1681622852483)(C:\Users\Administrator\Desktop\监听器.assets\image-20230416100740186.png)]

1.2.4 invokeBeanFactoryPostProcessor()

添加了一个。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7Wk9Dmgg-1681622852484)(C:\Users\Administrator\Desktop\监听器.assets\image-20230416111330686.png)]

1.2.5 registerListeners
protected void registerListeners() {
		//获取到AbstractApplicationContex.applicationListeners(15个)
		for (ApplicationListener<?> listener : getApplicationListeners()) {
            //添加到广播器中
            //AbstractApplicationEventMulticaster内部类ListenerRetriever
			getApplicationEventMulticaster().addApplicationListener(listener);
		}
    
    //&org.springframework.boot.autoconfigure.internalCachingMetadataReaderFactory
    //mvcResourceUrlProvider
    //springApplicationAdminRegistrar
	String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
    //添加到this.defaultRetriever.applicationListenerBeans.add(listenerBeanName);
    // //AbstractApplicationEventMulticaster内部类ListenerRetriever
		for (String listenerBeanName : listenerBeanNames) { 	getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
		}

		// Publish early application events now that we finally have a multicaster...
		Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
		this.earlyApplicationEvents = null;
		if (earlyEventsToProcess != null) {
			for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
				getApplicationEventMulticaster().multicastEvent(earlyEvent);
			}
		}
}


AbstractApplicationEventMulticaster.java
public void addApplicationListener(ApplicationListener<?> listener) {
		synchronized (this.retrievalMutex) {
			// Explicitly remove target for a proxy, if registered already,
			// in order to avoid double invocations of the same listener.
			Object singletonTarget = AopProxyUtils.getSingletonTarget(listener);
			if (singletonTarget instanceof ApplicationListener) {
				this.defaultRetriever.applicationListeners.remove(singletonTarget);
			}
			this.defaultRetriever.applicationListeners.add(listener);
			this.retrieverCache.clear();
		}
	}

经过以上,监听器的注入基本完成。

2. 广播执行

AbstractApplicationContext.java

@Override
	public void publishEvent(Object event) {
		publishEvent(event, null);
}


protected void publishEvent(Object event, @Nullable ResolvableType eventType) {
		
		//早期事件不为空
		if (this.earlyApplicationEvents != null) {
			this.earlyApplicationEvents.add(applicationEvent);
		}
		else {
            //调用多播器,继而调用监听器
			getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);
		}
      //....
}

调用多播器的逻辑,继而调用监听器的逻辑

	@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 {
            // 直接同步执行  
            //listener.onApplicationEvent(event); 其实就是回调执行逻辑   
			invokeListener(listener, event);
			}
		}
	}

对于getApplicationListeners(event, type)解析。还是在AbstractApplicationEventMulticaster.java类中,调用retrieveApplicationListeners(…)

//得到所有的监听器
private Collection<ApplicationListener<?>> retrieveApplicationListeners(
			ResolvableType eventType, @Nullable Class<?> sourceType, @Nullable ListenerRetriever retriever) {

    //最终返回的监听器
		List<ApplicationListener<?>> allListeners = new ArrayList<>();
    //项目设置进来的监听器addApplicationListener方法加入的,会保存在这里面
		Set<ApplicationListener<?>> listeners;
		Set<String> listenerBeans;
		synchronized (this.retrievalMutex) {
			listeners = new LinkedHashSet<>(this.defaultRetriever.applicationListeners);
			listenerBeans = new LinkedHashSet<>(this.defaultRetriever.applicationListenerBeans);
		}

		// Add programmatically registered listeners, including ones coming
		// from ApplicationListenerDetector (singleton beans and inner beans).
		for (ApplicationListener<?> listener : listeners) {
			if (supportsEvent(listener, eventType, sourceType)) {
				if (retriever != null) {
					retriever.applicationListeners.add(listener);
				}
				allListeners.add(listener);
			}
		}

		if (!listenerBeans.isEmpty()) {
			ConfigurableBeanFactory beanFactory = getBeanFactory();
			for (String listenerBeanName : listenerBeans) {
				try {
					if (supportsEvent(beanFactory, listenerBeanName, eventType)) {
						ApplicationListener<?> listener =
								beanFactory.getBean(listenerBeanName, ApplicationListener.class);
						if (!allListeners.contains(listener) && supportsEvent(listener, eventType, sourceType)) {
							if (retriever != null) {
								if (beanFactory.isSingleton(listenerBeanName)) {
									retriever.applicationListeners.add(listener);
								}
								else {
									retriever.applicationListenerBeans.add(listenerBeanName);
								}
							}
							allListeners.add(listener);
						}
					}
					else {
						Object listener = beanFactory.getSingleton(listenerBeanName);
						if (retriever != null) {
							retriever.applicationListeners.remove(listener);
						}
						allListeners.remove(listener);
					}
				}
				catch (NoSuchBeanDefinitionException ex) {
					// Singleton listener instance (without backing bean definition) disappeared -
					// probably in the middle of the destruction phase
				}
			}
		}

		AnnotationAwareOrderComparator.sort(allListeners);
		if (retriever != null && retriever.applicationListenerBeans.isEmpty()) {
			retriever.applicationListeners.clear();
			retriever.applicationListeners.addAll(allListeners);
		}
		return allListeners;
	}

3. 自定义的监听器

所有对象实例完成之后,

@Override
	public void preInstantiateSingletons() throws BeansException {
		// 将所有BeanDefinition的名字创建一个集合
		List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

		// Trigger initialization of all non-lazy singleton beans...
		// 触发所有非延迟加载单例bean的初始化,遍历集合的对象
		for (String beanName : beanNames) {
	    //。。。。。
		}

		// Trigger post-initialization callback for all applicable beans...
		// 遍历beanNames,触发所有SmartInitializingSingleton的后初始化回调
		for (String beanName : beanNames) {
			// 获取beanName对应的bean实例
			Object singletonInstance = getSingleton(beanName);
			// 判断singletonInstance是否实现了SmartInitializingSingleton接口
			if (singletonInstance instanceof SmartInitializingSingleton) {
				// 类型转换
				SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
				// 触发SmartInitializingSingleton实现类的afterSingletonsInstantiated方法
				if (System.getSecurityManager() != null) {
					AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
						smartSingleton.afterSingletonsInstantiated();
						return null;
					}, getAccessControlContext());
				}
				else {
					smartSingleton.afterSingletonsInstantiated();
				}
			}
		}
	}

EventListenerMethodProcessor.java。检查所有的bean对象

public void afterSingletonsInstantiated() {
		ConfigurableListableBeanFactory beanFactory = this.beanFactory;
		Assert.state(this.beanFactory != null, "No ConfigurableListableBeanFactory set");
		// 获取容器中所有bean组件的名称
		String[] beanNames = beanFactory.getBeanNamesForType(Object.class);
		for (String beanName : beanNames) {
			// 遍历每个bean组件,检测其中@EventListener注解方法,生成和注册ApplicationListener实例
			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 {
						// 针对一个bean的真正的@EventListener注解方法检测,ApplicationListener实例生成和注册
						processBean(beanName, type);
					}
					catch (Throwable ex) {
						throw new BeanInitializationException("Failed to process @EventListener " +
								"annotation on bean with name '" + beanName + "'", ex);
					}
				}
			}
		}
	}

processBean方法,注册监听器

private void processBean(final String beanName, final Class<?> targetType) {
		if (!this.nonAnnotatedClasses.contains(targetType) &&
				AnnotationUtils.isCandidateClass(targetType, EventListener.class) &&
				!isSpringContainerClass(targetType)) {

			Map<Method, EventListener> annotatedMethods = null;
			try {
				// 检测当前类targetType上使用了注解@EventListener的方法
				annotatedMethods = MethodIntrospector.selectMethods(targetType,
						(MethodIntrospector.MetadataLookup<EventListener>) 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)) {
				// 如果当前类targetType中没有任何使用了注解@EventListener的方法,则将该类保存到缓存nonAnnotatedClasses,从而
				// 避免当前处理方法重入该类,避免二次处理
				this.nonAnnotatedClasses.add(targetType);
				if (logger.isTraceEnabled()) {
					logger.trace("No @EventListener annotations found on bean class: " + targetType.getName());
				}
			}
			else {
				// Non-empty set of methods
				// 如果当前类targetType中有些方法使用了注解@EventListener,那么根据方法上的信息对应的创建和注册ApplicationListener实例
				ConfigurableApplicationContext context = this.applicationContext;
				Assert.state(context != null, "No ApplicationContext set");
				// 此处使用了this.eventListenerFactories,这些EventListenerFactory是在该类postProcessBeanFactory方法调用时被记录的
				List<EventListenerFactory> 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));
							// 如果当前EventListenerFactory支持处理该@EventListener注解的方法,则使用它创建ApplicationListener
							ApplicationListener<?> applicationListener =
									factory.createApplicationListener(beanName, targetType, methodToUse);
							if (applicationListener instanceof ApplicationListenerMethodAdapter) {
								((ApplicationListenerMethodAdapter) applicationListener).init(context, this.evaluator);
							}
							// 将创建的ApplicationListener加入到容器中
							context.addApplicationListener(applicationListener);
							break;
						}
					}
				}
				if (logger.isDebugEnabled()) {
					logger.debug(annotatedMethods.size() + " @EventListener methods processed on bean '" +
							beanName + "': " + annotatedMethods);
				}
			}
		}
	}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值