Spring Boot 3.x系列文章
- Spring Boot 2.7.8 中文参考指南(一)
- Spring Boot 2.7.8 中文参考指南(二)-Web
- Spring Boot 源码阅读初始化环境搭建
- Spring Boot 框架整体启动流程详解
- Spring Boot 系统初始化器详解
- Spring Boot 监听器详解
监听器的介绍
通过前面的几篇文章,我们都能看到
SpringApplicationRunListener
,SpringApplicationRunListener 是SpringApplication 的运行监听器,提供Spring Boot启动时各个运行状态的监听,可以在应用程序启动的时候执行一些自定义操作或记录一些信息。SpringApplicationRunListener 在
run
中加载
SpringApplicationRunListeners listeners = getRunListeners(args);
。
ApplicationListener
是Spring 提供的上下文监听器,可用于监听指定感兴趣的事件。
监听器的使用
SpringApplicationRunListener
SpringApplicationRunListener 的使用比较简单,实现该接口,并在
META-INF/spring.factories
中定义该实现
MyApplicationRunListener.java
publicclassMyApplicationRunListenerimplementsSpringApplicationRunListener{@Overridepublicvoidstarting(ConfigurableBootstrapContext bootstrapContext){System.out.println("Application 启动");}@OverridepublicvoidenvironmentPrepared(ConfigurableBootstrapContext bootstrapContext,ConfigurableEnvironment environment){System.out.println("环境已准备完毕");}@OverridepublicvoidcontextPrepared(ConfigurableApplicationContext context){System.out.println("在创建和准备ApplicationContext之后,但在加载源之前调用");}@OverridepublicvoidcontextLoaded(ConfigurableApplicationContext context){System.out.println("上下文准备完毕,未刷新");}@Overridepublicvoidstarted(ConfigurableApplicationContext context,Duration timeTaken){System.out.println("上下文已刷新,应用程序已启动,但尚未调用CommandLineRunners和ApplicationRunners");}@Overridepublicvoidready(ConfigurableApplicationContext context,Duration timeTaken){System.out.println("在刷新应用程序上下文并且调用了所有CommandLineRunner和ApplicationRunner之后,在运行方法完成之前立即调用");}@Overridepublicvoidfailed(ConfigurableApplicationContext context,Throwable exception){System.out.println("当运行应用程序时发生故障时调用");}}
META-INF/spring.factories
org.springframework.boot.SpringApplicationRunListener=com.springboot.demo.listeners.MyApplicationRunListener
运行情况:
ApplicationListener
1、实现ApplicationListener接口
MyApplicationListener.java
@Slf4jpublicclassMyApplicationListenerimplementsApplicationListener<ApplicationStartedEvent>{@OverridepublicvoidonApplicationEvent(ApplicationStartedEvent event){
log.info("应用启动完成");}}
META-INF/spring.factories
org.springframework.context.ApplicationListener=com.springboot.demo.listeners.MyApplicationListener
2、addListener
在springApplication 中添加,同样达到效果
SpringApplication springApplication =newSpringApplication(SpringBootDemoApplication.class);
springApplication.addListeners(newMyApplicationListener());
3、context.istener.classes
在配置文件中添加该配置,value为MyApplicationListener的全路径限定名
context:listener:classes: com.springboot.demo.listeners.MyApplicationListener
4、@EventListener
该注解是spring 提供的方式,支持同时监听多种事件,支持SpEL表达式
@Component@Slf4jpublicclassMyApplicationListener2{//监听单个事件@EventListenerpublicvoidlistenerApplicationStarted(ApplicationStartedEvent event){
log.info("应用启动完成");}@EventListener({ApplicationEnvironmentPreparedEvent.class})publicvoidlistenerApplicationEnv(){//实际测试,没有监听到,后面说明原理
log.info("监听到了环境准备完成事件");}//监听多个事件@EventListener({ApplicationReadyEvent.class,ApplicationStartedEvent.class})publicvoidlistenerApplication(){
log.info("监听到了多个事件");}//自己发布了一个Person事件,Person并没有继承ApplicationEvent@EventListenerpublicvoidmyCustomListener(Person person){
log.info("监听到自己发布的事件,{}", person);}//只有Person事件中name属性值为csdn时才接收到@EventListener(condition ="#person.name == 'csdn'")publicvoidmyCustomListener2(Person person){
log.info("SpEL表达式监听到自己发布的事件,{}", person);}}
原理解析
SpringApplicationRunListener 的原理在之前的文章都有体现,可以查看《Spring Boot 框架整体启动流程详解》,我们只需要关注ApplicationListener。
Spring Boot 中不同的使用方式有不同的加载,我们一个个来分析。
1、从spring.factories中加载
首先Spring Boot 会在SpringApplication初始化的时候从
META-INF/spring.factories
中加载ApplicationListener的实现,并保存在
private List<ApplicationListener<?>> listeners;
中,待后续使用。
第二个关键是
EventPublishingRunListener
,在run方法中通过
SpringApplicationRunListeners listeners = getRunListeners(args);
加载,getRunListeners 从 spring.factories加载SpringApplicationRunListener的实现保存在SpringApplicationRunListeners内部,其相当于是代理器,Spring Boot 内部只定义了一个EventPublishingRunListener实现。
在Spring Boot 中在不同的阶段调用不同的SpringApplicationRunListeners方法,如图只是部分
以
starting
为例,会在SpringApplicationRunListeners内部通过循环前期加载的SpringApplicationRunListener实现,此处只需要关注
EventPublishingRunListener
进入
EventPublishingRunListener
的
starting
方法中,starting调用同类的multicastInitialEvent,事件定义为ApplicationStartingEvent
privatevoidmulticastInitialEvent(ApplicationEvent event){refreshApplicationListeners();this.initialMulticaster.multicastEvent(event);}
refreshApplicationListeners
会从SpringApplication保存的listeners中读取初始化时加载的ApplicationListener实现,并添加到
SimpleApplicationEventMulticaster
的内部类DefaultListenerRetriever中,待后续使用。
privatevoidrefreshApplicationListeners(){this.application.getListeners().forEach(this.initialMulticaster::addApplicationListener);}
第三个关键是
SimpleApplicationEventMulticaster
,
this.initialMulticaster.multicastEvent(event)
调用到了SimpleApplicationEventMulticaster中,multicastEvent又调用了一个同名方法。
publicvoidmulticastEvent(ApplicationEvent event){multicastEvent(event,null);}@OverridepublicvoidmulticastEvent(ApplicationEvent event,@NullableResolvableType eventType){//获取事件类的类型信息ResolvableType type =(eventType !=null? eventType :ResolvableType.forInstance(event));// 获取执行事件的线程池,如果设置了,可以异步执行Executor executor =getTaskExecutor();//获取指定事件类型的监听器集合for(ApplicationListener<?> listener :getApplicationListeners(event, type)){//如果定义了执行线程池,则用线程池调用if(executor !=null){
executor.execute(()->invokeListener(listener, event));}else{//同步调用监听器invokeListener(listener, event);}}}protectedvoidinvokeListener(ApplicationListener<?> listener,ApplicationEvent event){//获取失败处理器ErrorHandler errorHandler =getErrorHandler();if(errorHandler !=null){try{doInvokeListener(listener, event);}catch(Throwable err){
errorHandler.handleError(err);}}else{doInvokeListener(listener, event);}}@SuppressWarnings({"rawtypes","unchecked"})privatevoiddoInvokeListener(ApplicationListener listener,ApplicationEvent event){try{//此处执行事件监听器的onApplicationEvent方法
listener.onApplicationEvent(event);}catch(ClassCastException ex){String msg = ex.getMessage();if(msg ==null||matchesClassCastMessage(msg, event.getClass())||(event instanceofPayloadApplicationEvent payloadEvent &&matchesClassCastMessage(msg, payloadEvent.getPayload().getClass()))){// Possibly a lambda-defined listener which we could not resolve the generic event type for// -> let's suppress the exception.Log loggerToUse =this.lazyLogger;if(loggerToUse ==null){
loggerToUse =LogFactory.getLog(getClass());this.lazyLogger = loggerToUse;}if(loggerToUse.isTraceEnabled()){
loggerToUse.trace("Non-matching event type for listener: "+ listener, ex);}}else{throw ex;}}}
实际上到这里流程已经走完了,最后
listener.onApplicationEvent(event);
调用到自定义的
MyApplicationListener
中。
对于如何获取指定事件类型的监听器集合,
getApplicationListeners(event, type)
,代码比较复杂,可看也可不看。
getApplicationListeners 方法在SimpleApplicationEventMulticaster 的父类AbstractApplicationEventMulticaster中,传入传播的事件类bean和事件的类型信息。
protectedCollection<ApplicationListener<?>>getApplicationListeners(ApplicationEvent event,ResolvableType eventType){//获取事件发生的对象Object source = event.getSource();Class<?> sourceType =(source !=null? source.getClass():null);//根据事件的类型信息和源对象组成一个监听器的缓存keyListenerCacheKey cacheKey =newListenerCacheKey(eventType, sourceType);// 创建一个新的监听器检索缓存CachedListenerRetriever newRetriever =null;// 根据key从检索缓存中获取缓存的监听器封装类CachedListenerRetriever existingRetriever =this.retrieverCache.get(cacheKey);//如果不存在if(existingRetriever ==null){//判断事件类型和源对象能否用指定的classLoader加载// 创建并缓存一个新的ListenerRetrieverif(this.beanClassLoader ==null||(ClassUtils.isCacheSafe(event.getClass(),this.beanClassLoader)&&(sourceType ==null||ClassUtils.isCacheSafe(sourceType,this.beanClassLoader)))){
newRetriever =newCachedListenerRetriever();//如果指定键没有关联值,则存入新值,返回null,有关联值返回关联值
existingRetriever =this.retrieverCache.putIfAbsent(cacheKey, newRetriever);//有关联值,就不填充新值,将创建的对象取消关联if(existingRetriever !=null){
newRetriever =null;}}}//缓存检索器中有值,就返回缓存的事件监听器列表if(existingRetriever !=null){Collection<ApplicationListener<?>> result = existingRetriever.getApplicationListeners();if(result !=null){return result;}}//缓存检索器中没有值的话,继续检索returnretrieveApplicationListeners(eventType, sourceType, newRetriever);}
privateCollection<ApplicationListener<?>>retrieveApplicationListeners(ResolvableType eventType,@NullableClass<?> sourceType,@NullableCachedListenerRetriever retriever){List<ApplicationListener<?>> allListeners =newArrayList<>();Set<ApplicationListener<?>> filteredListeners =(retriever !=null?newLinkedHashSet<>():null);Set<String> filteredListenerBeans =(retriever !=null?newLinkedHashSet<>():null);Set<ApplicationListener<?>> listeners;Set<String> listenerBeans;//从默认检索器中读取监听器列表和监听器bean名称synchronized(this.defaultRetriever){
listeners =newLinkedHashSet<>(this.defaultRetriever.applicationListeners);
listenerBeans =newLinkedHashSet<>(this.defaultRetriever.applicationListenerBeans);}// 循环添加已经注册的监听器,包括ApplicationListenerDetector加载的监听器for(ApplicationListener<?> listener : listeners){//检查指定的监听器是否是需要关注的事件if(supportsEvent(listener, eventType, sourceType)){if(retriever !=null){
filteredListeners.add(listener);}
allListeners.add(listener);}}// 通过bean名称来添加监听器,可能与上面的方式重叠,但这里会有一些新的元数据if(!listenerBeans.isEmpty()){//获取bean工厂ConfigurableBeanFactory beanFactory =getBeanFactory();for(String listenerBeanName : listenerBeans){try{//判断指定的监听器bean是否是需要关注的事件if(supportsEvent(beanFactory, listenerBeanName, eventType)){//获取监听器beanApplicationListener<?> listener =
beanFactory.getBean(listenerBeanName,ApplicationListener.class);//最终判断if(!allListeners.contains(listener)&&supportsEvent(listener, eventType, sourceType)){if(retriever !=null){if(beanFactory.isSingleton(listenerBeanName)){
filteredListeners.add(listener);}else{
filteredListenerBeans.add(listenerBeanName);}}
allListeners.add(listener);}}else{// 移除不支持的监听器Object listener = beanFactory.getSingleton(listenerBeanName);if(retriever !=null){
filteredListeners.remove(listener);}
allListeners.remove(listener);}}catch(NoSuchBeanDefinitionException ex){}}}//排序AnnotationAwareOrderComparator.sort(allListeners);if(retriever !=null){if(filteredListenerBeans.isEmpty()){
retriever.applicationListeners =newLinkedHashSet<>(allListeners);
retriever.applicationListenerBeans = filteredListenerBeans;}else{
retriever.applicationListeners = filteredListeners;
retriever.applicationListenerBeans = filteredListenerBeans;}}return allListeners;}
看下最终判断的部分:
supportsEvent(listener, eventType, sourceType)
protectedbooleansupportsEvent(ApplicationListener<?> listener,ResolvableType eventType,@NullableClass<?> sourceType){GenericApplicationListener smartListener =(listener instanceofGenericApplicationListener gal ? gal :newGenericApplicationListenerAdapter(listener));//通过判断给定的事件类型是否与要关注的事件类型一致,并且支持给定的源类型return(smartListener.supportsEventType(eventType)&& smartListener.supportsSourceType(sourceType));}
这里会将监听器包装成GenericApplicationListenerAdapter,在构造器中解析出监听器关注的事件类型信息。
publicGenericApplicationListenerAdapter(ApplicationListener<?> delegate){Assert.notNull(delegate,"Delegate listener must not be null");this.delegate =(ApplicationListener<ApplicationEvent>) delegate;//解析出事件类型信息this.declaredEventType =resolveDeclaredEventType(this.delegate);}
publicbooleansupportsEventType(ResolvableType eventType){//如果是GenericApplicationListener 的实现,它扩展了SmartApplicationListenerif(this.delegate instanceofGenericApplicationListener gal){return gal.supportsEventType(eventType);}//如果是SmartApplicationListener的实现elseif(this.delegate instanceofSmartApplicationListener sal){Class<?extendsApplicationEvent> eventClass =(Class<?extendsApplicationEvent>) eventType.resolve();return(eventClass !=null&& sal.supportsEventType(eventClass));}else{//其他类型判断return(this.declaredEventType ==null||this.declaredEventType.isAssignableFrom(eventType));}}@OverridepublicbooleansupportsSourceType(@NullableClass<?> sourceType){return(!(this.delegate instanceofSmartApplicationListener sal)|| sal.supportsSourceType(sourceType));}
2、addListener
由于addListener是在run方法执行之前就添加到了SpringApplication中,所以加载原理同第一种方式相同
3、context.listener.classes
该配置的监听器,由Spring Boot 内置的
DelegatingApplicationListener
处理,该监听器定义在Spring Boot Jar包的
META-INF/spring.factories
中。
publicvoidonApplicationEvent(ApplicationEvent event){//环境准备完毕if(event instanceofApplicationEnvironmentPreparedEvent preparedEvent){//从context.listener.classes加载配置的事件监听器List<ApplicationListener<ApplicationEvent>> delegates =getListeners(preparedEvent.getEnvironment());if(delegates.isEmpty()){return;}//新创建一个SimpleApplicationEventMulticaster,跟以前用的不是同一个this.multicaster =newSimpleApplicationEventMulticaster();for(ApplicationListener<ApplicationEvent> listener : delegates){this.multicaster.addApplicationListener(listener);}}if(this.multicaster !=null){//监听到其他事件的时候向所有注册在该广播器上的监听器广播事件this.multicaster.multicastEvent(event);}}
this.multicaster.multicastEvent(event);
后面的逻辑与前面的相同
4、@EventListener
在之前的实例中,我们监听了一个ApplicationEnvironmentPreparedEvent事件,但实际测试却没有监听到,因为@EventListener要在SpringApplication.run的
refreshContext
中才会被加载,而ApplicationEnvironmentPreparedEvent事件发生在
refreshContext
之前。
@EventListener 是Spring 提供的注解,在
EventListenerMethodProcessor
中被加载,并包装成
ApplicationListener
实例。
Spring Boot 的refreshContext 最终会调用到Spring 的
AbstractApplicationContext refresh()
。
EventListenerMethodProcessor
是一个BeanFactoryPostProcessor,会在refresh 的invokeBeanFactoryPostProcessors(beanFactory) 中进行调用
protectedvoidinvokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory){//使用注册委托类处理BeanFactoryPostProcessor的实现PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory,getBeanFactoryPostProcessors());// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime// (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)if(!NativeDetector.inNativeImage()&& beanFactory.getTempClassLoader()==null&& beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)){
beanFactory.addBeanPostProcessor(newLoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(newContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));}}
getBeanFactoryPostProcessors()
会获取已经加载的BeanFactoryPostProcessor实现,比如准备上下文中的PropertySourceOrderingBeanFactoryPostProcessor。
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors
内部的方法很长
publicstaticvoidinvokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory,List<BeanFactoryPostProcessor> beanFactoryPostProcessors){Set<String> processedBeans =newHashSet<>();//首先处理是BeanDefinitionRegistry的实例if(beanFactory instanceofBeanDefinitionRegistry registry){List<BeanFactoryPostProcessor> regularPostProcessors =newArrayList<>();List<BeanDefinitionRegistryPostProcessor> registryProcessors =newArrayList<>();for(BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors){if(postProcessor instanceofBeanDefinitionRegistryPostProcessor registryProcessor){
registryProcessor.postProcessBeanDefinitionRegistry(registry);
registryProcessors.add(registryProcessor);}else{
regularPostProcessors.add(postProcessor);}}// 然后其中分别处理实现了 PriorityOrdered、Ordered 和其余的处理器List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors =newArrayList<>();//处理实现了PriorityOrdered的处理器String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class,true,false);for(String ppName : postProcessorNames){if(beanFactory.isTypeMatch(ppName,PriorityOrdered.class)){
currentRegistryProcessors.add(beanFactory.getBean(ppName,BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);}}sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
currentRegistryProcessors.clear();// 处理实现了Ordered的处理器
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class,true,false);for(String ppName : postProcessorNames){if(!processedBeans.contains(ppName)&& beanFactory.isTypeMatch(ppName,Ordered.class)){
currentRegistryProcessors.add(beanFactory.getBean(ppName,BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);}}sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
currentRegistryProcessors.clear();// 最后是剩下的处理器boolean reiterate =true;while(reiterate){
reiterate =false;
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class,true,false);for(String ppName : postProcessorNames){if(!processedBeans.contains(ppName)){
currentRegistryProcessors.add(beanFactory.getBean(ppName,BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
reiterate =true;}}sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
currentRegistryProcessors.clear();}// 调用迄今为止处理的所有处理器的postProcessBeanFactory回调invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);}else{// 其他情况调用在上下文实例中注册的工厂处理程序invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);}// 处理 BeanFactoryPostProcessor 实现的实例String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class,true,false);//在实现PriorityOrdered、Ordered和其他的BeanFactoryPostProcessors之间分离List<BeanFactoryPostProcessor> priorityOrderedPostProcessors =newArrayList<>();List<String> orderedPostProcessorNames =newArrayList<>();List<String> nonOrderedPostProcessorNames =newArrayList<>();for(String ppName : postProcessorNames){if(processedBeans.contains(ppName)){// 跳过-已在上面的第一阶段中处理}elseif(beanFactory.isTypeMatch(ppName,PriorityOrdered.class)){
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName,BeanFactoryPostProcessor.class));}elseif(beanFactory.isTypeMatch(ppName,Ordered.class)){
orderedPostProcessorNames.add(ppName);}else{
nonOrderedPostProcessorNames.add(ppName);}}// 首先,调用实现PriorityOrdered的BeanFactoryPostProcessorssortPostProcessors(priorityOrderedPostProcessors, beanFactory);invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);//调用实现Ordered的BeanFactoryPostProcessorsList<BeanFactoryPostProcessor> orderedPostProcessors =newArrayList<>(orderedPostProcessorNames.size());for(String postProcessorName : orderedPostProcessorNames){
orderedPostProcessors.add(beanFactory.getBean(postProcessorName,BeanFactoryPostProcessor.class));}sortPostProcessors(orderedPostProcessors, beanFactory);invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);// 最后调用其他的BeanFactoryPostProcessorsList<BeanFactoryPostProcessor> nonOrderedPostProcessors =newArrayList<>(nonOrderedPostProcessorNames.size());for(String postProcessorName : nonOrderedPostProcessorNames){
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName,BeanFactoryPostProcessor.class));}//EventListenerMethodProcessor会在此处被调用invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);//清除缓存的合并bean定义,因为后处理程序可能已经修改了原始元数据,例如替换值中的占位符。。。
beanFactory.clearMetadataCache();}
privatestaticvoidinvokeBeanFactoryPostProcessors(Collection<?extendsBeanFactoryPostProcessor> postProcessors,ConfigurableListableBeanFactory beanFactory){for(BeanFactoryPostProcessor postProcessor : postProcessors){//步骤记录器StartupStep postProcessBeanFactory = beanFactory.getApplicationStartup().start("spring.context.bean-factory.post-process").tag("postProcessor", postProcessor::toString);//循环调用postProcessBeanFactory
postProcessor.postProcessBeanFactory(beanFactory);
postProcessBeanFactory.end();}}
EventListenerMethodProcessor
类中:
publicvoidpostProcessBeanFactory(ConfigurableListableBeanFactory beanFactory){this.beanFactory = beanFactory;//获取EventListenerFactory实现类,其用于处理EventListener注解,//将其封装成ApplicationListenerMap<String,EventListenerFactory> beans = beanFactory.getBeansOfType(EventListenerFactory.class,false,false);List<EventListenerFactory> factories =newArrayList<>(beans.values());AnnotationAwareOrderComparator.sort(factories);this.eventListenerFactories = factories;}
EventListenerMethodProcessor
实现了SmartInitializingSingleton接口,会在refresh中的
finishBeanFactoryInitialization(beanFactory)
处调用,finishBeanFactoryInitialization 的作用是实例化所有剩余的非惰性单例。
DefaultListableBeanFactory
类中:
//预实例化所有非懒加载的单例 bean,并触发所有适用 bean 的初始化后回调。publicvoidpreInstantiateSingletons()throwsBeansException{if(logger.isTraceEnabled()){
logger.trace("Pre-instantiating singletons in "+this);}// 访问 beanDefinitionNames,以允许初始化方法注册新的 bean 定义的列表的副本List<String> beanNames =newArrayList<>(this.beanDefinitionNames);// 触发所有非延迟加载的单例 bean 的实例化for(String beanName : beanNames){RootBeanDefinition bd =getMergedLocalBeanDefinition(beanName);if(!bd.isAbstract()&& bd.isSingleton()&&!bd.isLazyInit()){//如果是工厂 bean,检查是否需要实例化if(isFactoryBean(beanName)){Object bean =getBean(FACTORY_BEAN_PREFIX + beanName);if(bean instanceofSmartFactoryBean<?> smartFactoryBean && smartFactoryBean.isEagerInit()){getBean(beanName);}}//如果不是工厂bean,则实例化 beanelse{getBean(beanName);}}}// 触发所有适用bean的初始化后回调for(String beanName : beanNames){Object singletonInstance =getSingleton(beanName);if(singletonInstance instanceofSmartInitializingSingleton smartSingleton){// 启动一个 smart-initialize 的 StartupStep 作为性能分析;// 在执行完 smartSingleton.afterSingletonsInstantiated() 之后结束这个 StartupStep。StartupStep smartInitialize =this.getApplicationStartup().start("spring.beans.smart-initialize").tag("beanName", beanName);
smartSingleton.afterSingletonsInstantiated();
smartInitialize.end();}}}
通过
smartSingleton.afterSingletonsInstantiated()
又执行到了
EventListenerMethodProcessor
的
afterSingletonsInstantiated
,后面又是一长串,我们直接看最后的重点吧。
首先根据@EventListener创建成ApplicationListener,然后通过
addApplicationListener
将监听器存入上下文中,后面的逻辑跟前面是相同的。
内置的监听器
Spring Boot 内置了不少监听器,每个监听器都有自己的作用
- ClearCachesApplicationListener 应用上下文加载完成后对缓存做清除工作
- ParentContextCloserApplicationListener 父应用程序上下文关闭时,会将关闭事件向下传播以关闭该应用程序上下文
- FileEncodingApplicationListener 用于监听应用程序环境准备完毕时,如果系统文件编码(spring.mandatory-file-encoding)与环境中配置的值(file.encoding)不匹配时(忽略大小写),会抛出异常,并停止应用程序
- AnsiOutputApplicationListener 根据spring.output.ansi.enabled参数配置AnsiOutput
- DelegatingApplicationListener 用于委托管理context.listener.classes中配置的监听器
- LoggingApplicationListener 配置和初始化Spring Boot 的日志系统
- EnvironmentPostProcessorApplicationListener 管理spring.factories文件中注册的EnvironmentPostProcessors
内置的事件
Spring Boot 包中部分事件:
BootstrapContextClosedEvent、ExitCodeEvent、AvailabilityChangeEvent、ParentContextAvailableEvent、ApplicationContextInitializedEvent、ApplicationEnvironmentPreparedEvent、ApplicationFailedEvent、ApplicationPreparedEvent、ApplicationReadyEvent、ApplicationStartedEvent、ApplicationStartingEvent、WebServerInitializedEvent、ReactiveWebServerInitializedEvent、ServletWebServerInitializedEvent
Spring 包中部分事件:
ContextClosedEvent、ContextRefreshedEvent、ContextStartedEvent、ContextStoppedEvent、ServletRequestHandledEvent
总结
最后还是用一张图来总结整个流程
作者其他文章:
Prometheus 系列文章
- Prometheus 的介绍和安装
- 直观感受PromQL及其数据类型
- PromQL之选择器和运算符
- PromQL之函数
- Prometheus 告警机制介绍及命令解读
- Prometheus 告警模块配置深度解析
- Prometheus 配置身份认证
- Prometheus 动态拉取监控服务
- Prometheus 监控云Mysql和自建Mysql
Grafana 系列文章,版本:OOS v9.3.1
- Grafana 的介绍和安装
- Grafana监控大屏配置参数介绍(一)
- Grafana监控大屏配置参数介绍(二)
- Grafana监控大屏可视化图表
- Grafana 查询数据和转换数据
- Grafana 告警模块介绍
- Grafana 告警接入飞书通知
Spring Boot Admin 系列
- Spring Boot Admin 参考指南
- SpringBoot Admin服务离线、不显示健康信息的问题
- Spring Boot Admin2 @EnableAdminServer的加载
- Spring Boot Admin2 AdminServerAutoConfiguration详解
- Spring Boot Admin2 实例状态监控详解
- Spring Boot Admin2 自定义JVM监控通知
- Spring Boot Admin2 自定义异常监控
- Spring Boot Admin 监控指标接入Grafana可视化
版权归原作者 阿提说说 所有, 如有侵权,请联系我们删除。