Spring底层如何执行?

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


Spring底层如何执行

首先定义了application.xml在这里插入图片描述
接下来我们来看下 BeanFactory context = new ClassPathXmlApplicationContext(“application.xml”); 内部是如何执行的
在这里插入图片描述

refresh()

回想下Spring的基本运行流程,想一想我们第一步应该做什么?
第一步是创建我们的BeanFactory对象

@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.
			//告诉子类刷新内部bean工厂。
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			// Prepare the bean factory for use in this context.
			//对beanFactory进行一些初始化工作
			prepareBeanFactory(beanFactory);

			try {
				// Allows post-processing of the bean factory in context subclasses.
				// 对 BeanFactory 做额外处理。默认没有实现
				postProcessBeanFactory(beanFactory);

				// Invoke factory processors registered as beans in the context.
				// 激活各种BeanFactory后处理器
				invokeBeanFactoryPostProcessors(beanFactory);

				// Register bean processors that intercept bean creation.
				// 注册并创建拦截bean创建的(BeanPostProcessors) bean处理器
				registerBeanPostProcessors(beanFactory);

				// Initialize message source for this context.
				// 为上下文初始化Message源,即不同语言的消息体,国际化处理
				initMessageSource();

				// Initialize event multicaster for this context.
				// 初始化应用消息广播器,并放入"applicationEventMulticaster" bean 中,用来发布监听事件
				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();
			}
		}
	}

一、prepareRefresh() 准备刷新的工作

初始化前的准备工作,对系统属性或者环境变量进行准备及验证。在某些情况下项目的使用需要读取某些系统变量,那么在启动时候,就可以通过准备函数来进行参数的校验。
在这里插入图片描述

  1. 设置上下文的启动日期和激活标志,将 startupDate 设置为当前时间戳,将 closed 标志设为false(表示上下文未关闭),将 active 标志设为 true(表示上下文处于活动状.符属性源。这个步骤可以理解为加载和准备上下文所需的配置属性,例如从属性文件中读取配置项。
  2. 验证所有标记为(必需)的属性是否可解析。这是为了确保应用程序上下文所需的属性在配置中可用,并通过验证确保了属性的正确性和有效性。
initPropertySources()

这个方法是为了给用户自己实现初始化逻辑,可以初始化一些属性资源。因此Spring并没有实现这个方法
在这里插入图片描述

validateRequiredProperties( )

这个方法是对一些启动必须的属性的验证

public void validateRequiredProperties() {
    //创建一个 MissingRequiredPropertiesException 异常对象,用于收集缺失的必需属性
    MissingRequiredPropertiesException ex = new MissingRequiredPropertiesException(); 
    //遍历 requiredProperties 集合中的每个属性键
    Iterator var2 = this.requiredProperties.iterator();

    while(var2.hasNext()) {
        String key = (String) var2.next();
        if (this.getProperty(key) == null) {
            //为空,将该属性键添加到 MissingRequiredPropertiesException 对象中的缺失属性列表
            ex.addMissingRequiredProperty(key);
        }
    }
    //主要目的是验证在应用程序上下文中标记为必需的属性是否在配置中已解析。如果有任何缺失的必需属性,则会抛出异常
    if (!ex.getMissingRequiredProperties().isEmpty()) {
        throw ex;
    }
}

二、obtainFreshBeanFactory()

obtainFreshBeanFactory() 获取BeanFactory,这个方法的作用是刷新上下文的内部 BeanFactory。它会调用 refreshBeanFactory() 方法来重新加载配置,并返回刷新后的 BeanFactory 实例
obtainFreshBeanFactory() 方法应该涉及 BeanFactory 的实例化,以确保获得一个全新的 BeanFactory 实例
在这里插入图片描述

refreshBeanFactory()

此方法是一个抽象方法,需要由子类实现。子类负责执行实际的配置加载操作。该方法将在 refresh() 方法中的其他初始化工作之前调用。
负责刷新上下文的 BeanFactory。它会关闭之前的 BeanFactory(如果有),创建一个新的 BeanFactory,并加载配置信息。这个步骤是 Spring 上下文初始化的关键,确保上下文中的 beans 和配置是最新的
在这里插入图片描述
两种方式实现该方法:

  • 要么创建一个新的 BeanFactory 并持有对它的引用
  • 要么返回它持有的单个 BeanFactory 实例。
  • 如果多次刷新上下文,通常会抛出 IllegalStateException

BeanFactory的创建委托给了 refreshBeanFactory() 方法,refreshBeanFactory() 方法被两个类实现AbstractRefreshableApplicationContext 和 GenericApplicationContext。

AbstractRefreshableApplicationContext 实现

此实现执行此上下文的底层 BeanFactory 的实际刷新操作,(如果有)关闭先前的 BeanFactory,并为上下文的生命周期的下一个阶段初始化一个新的 BeanFactory。
在这里插入图片描述
在这里插入图片描述
loadBeanDefinitions(beanFactory); 执行后,这里可以看到我们加载的xml的BeanDefinition信息

GenericApplicationContext 实现

什么也不做:我们持有一个单个的内部 BeanFactory,依赖于调用者通过我们的公共方法(或 BeanFactory 的方法)注册 bean。
它会检查是否已经进行了刷新操作,如果已经刷新过了,则会抛出 IllegalStateException。此实现适用于那些只需要在初始化时设置 BeanFactory,而无需重新加载配置的情况。
在这里插入图片描述
这里可以看到,GenericApplicationContext 中的实现非常简单。只是简单的将刷新状态置为true。
需要注意的是 this.beanFactory 的实际类型为 DefaultListableBeanFactory。在GenericApplicationContext 的构造函数中进行了对象创建或指定。如下:
在这里插入图片描述

prepareBeanFactory() 准备BeanFactory

prepareBeanFactory() 对beanFactry 做了一些准备工作,设置了一些属性来扩展功能
该方法在初始化 BeanFactory 时会被调用,它确保上下文中的 beans 能够正确地处理,并配置了一些重要的特性和后置处理器
作用是配置 BeanFactory 的标准上下文特性,例如类加载器和后置处理器等等就是对上述创建的BeanFactory 空bean 做一些set注入。
我们这里看 AbstractApplicationContext#prepareBeanFactory 的实现。具体代码如下:

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
		// Tell the internal bean factory to use the context's class loader etc.
		// 将当前上下文的类加载器getClassLoader设置为 BeanFactory 的类加载器
		beanFactory.setBeanClassLoader(getClassLoader());
		// 设置beanFactory 的表达式语言处理器,Spring3 增加了表达式语言的支持
		// 默认可以使用 #{bean.xxx}的形式来调用处理相关属性。
		beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
		// 为beanFactory 增加一个默认的propertyEditor,这个主要是针对bean的属性等设置管理的一个工具,用于处理属性类型转换
		beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

		// Configure the bean factory with context callbacks.
		// 添加 ApplicationContextAwareProcessor 作为后置处理器
		beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
		// 设置了几个忽略自动装配的接口,这些接口的实现类将不会被自动注入相关依赖
		beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
		beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
		beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
		beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
		beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
		beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);

		// BeanFactory interface not registered as resolvable type in a plain factory.
		// MessageSource registered (and found for autowiring) as a bean.
		// 设置了几个自动装配的特殊规则,这些类型的实例将作为特殊的解析依赖,可以在自动装配时自动注入
		beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
		beanFactory.registerResolvableDependency(ResourceLoader.class, this);
		beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
		beanFactory.registerResolvableDependency(ApplicationContext.class, this);

		// Register early post-processor for detecting inner beans as ApplicationListeners.
		// 注册用于检测内部 beans 是否为 ApplicationListeners 的后置处理器(ApplicationListenerDetector)
		beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
		
		// Detect a LoadTimeWeaver and prepare for weaving, if found.
		// 增加对 AspectJ的支持
		// 检测是否存在 LoadTimeWeaver 并进行相关配置。LoadTimeWeaver 可用于支持 AspectJ 类型的织入。
		if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
		// 添加 LoadTimeWeaverAwareProcessor 作为后置处理器,用于处理实现了 LoadTimeWeaverAware 接口的 bean。
			beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
			// Set a temporary ClassLoader for type matching.
			// 为类型匹配设置一个临时的 ClassLoader。这是由于在 LoadTimeWeaver 进行类型匹配时需要使用特殊的 ClassLoader。
			beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
		}

		// Register default environment beans.
		// 添加默认的系统环境bean,检查是否已经注册了默认的环境 bean,如果没有,则将其注册为单例 bean
		if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
			beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
		}
		if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
			beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
		}
		if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
			beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
		}
	}

postProcessBeanFactory()

对 BeanFactory 做额外处理。默认没有实现,是个空方法。
postProcessBeanFactory() 方法是在标准初始化之后修改应用程序上下文的内部 BeanFactory。在此阶段,所有的 bean 定义都已加载,但还没有实例化任何 bean。这允许在某些特定的 ApplicationContext 实现中注册特殊的 BeanPostProcessors 等。

这个方法的目的是对 BeanFactory 进行后续处理,根据需要进行一些自定义的配置。
例如,你可以注册一个 BeanFactoryPostProcessor,用于修改已加载的 bean 定义,进一步定制 BeanFactory 的行为。在这个方法中,你可以通过传入的 beanFactory 参数来访问和操作 BeanFactory 的各种属性和方法,以完成你的自定义逻辑。

注意:postProcessBeanFactory() 方法提供了在BeanFactory 初始化之后 但在 加载任何 bean 实例之前修改 BeanFactory 的机会。这个方法可以被用来修改 BeanFactory 的配置,例如添加额外的 BeanPostProcessor 实例或其他的自定义组件。但它一般不用于直接修改加载的 XML 或其他配置文件中的具体 bean 定义信息。

如果需要修改已经加载的 XML 或其他配置文件中的 bean 定义信息,更常见的做法是编写自定义的 BeanDefinitionRegistryPostProcessor。这个接口规定了在加载完 bean 定义后对它们进行修改的方法,例如修改 bean 的属性、添加或删除 bean 定义等。
在这里插入图片描述

invokeBeanFactoryPostProcessors()

主要是激活各种 BeanFactoryPostProcessors,处理bean的定义信息BeanDefinition,生成的注入容器中的bean 的 BeanDefinition
实例化并调用所有已注册的 BeanFactoryPostProcessor beans
在这里插入图片描述

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
    // 调用 PostProcessorRegistrationDelegate 的 invokeBeanFactoryPostProcessors 方法
    // 传入 beanFactory 和已注册的 BeanFactoryPostProcessor 实例列表
    PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

    // 检测是否存在LoadTimeWeaver,并为织入操作做准备
    if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
        // 创建 LoadTimeWeaverAwareProcessor 实例
        beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
        // 设置临时的类加载器
        beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
    }
}
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors()

用于实例化和调用所有已注册的 BeanFactoryPostProcessor 实例

public static void invokeBeanFactoryPostProcessors(
		ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

	// Invoke BeanDefinitionRegistryPostProcessors first, if any.
	// 首先调用 BeanDefinitionRegistryPostProcessor
	Set<String> processedBeans = new HashSet<>();

	if (beanFactory instanceof BeanDefinitionRegistry) {
		BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
		List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
		List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
		// 遍历已注册的 BeanFactoryPostProcessor 实例
		for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
			if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
				// 如果实现了 BeanDefinitionRegistryPostProcessor 接口,调用其 postProcessBeanDefinitionRegistry 方法
				BeanDefinitionRegistryPostProcessor registryProcessor = (BeanDefinitionRegistryPostProcessor) postProcessor;
				registryProcessor.postProcessBeanDefinitionRegistry(registry);
				registryProcessors.add(registryProcessor);
			} else {
				// 否则,将其放入常规的后处理器列表中
				regularPostProcessors.add(postProcessor);
			}
		}

		// ...

		// 最后,调用之前收集到的BeanDefinitionRegistryPostProcessor的postProcessBeanFactory方法
		invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
		invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
	} else {
		// ...

		// 如果不是 BeanDefinitionRegistry,则直接调用后处理器
		invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
	}

	// ...

	// 最后刷新 BeanFactory 的元数据缓存
	beanFactory.clearMetadataCache();
}

registerBeanPostProcessors()

注册并调用所有已注册的 BeanPostProcessor bean,遵循明确的顺序(如果有)必须在实例化应用程序 bean 之前调用。
注册所有的BeanPostProcessors beans 但是只是注册不会执行,这里执行提前说注册bean,提前把准备工作注册好。BeanPostProcessor 在这一步已经完成了创建

BeanFactoryPostProcessor :对没有实例化之前的BeanDefinition,对Bean的配置元数据进行操作
BeanPostProcessor :作用:在Bean对象在实例化和依赖注入完毕后,在显示调用初始化方法的前后添加我们自己的逻辑。注意是Bean实例化完毕后及依赖注入完成后触发的
在这里插入图片描述

在这里插入图片描述

/**
 * 注册并调用所有已注册的 BeanPostProcessor bean,遵循明确的顺序(如果有)。
 * <p>必须在实例化应用程序 bean 之前调用。
 */
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
	PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}


public static void registerBeanPostProcessors(
		ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {

	// 获取所有注册的 BeanPostProcessor 的名称
	String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

	// 注册一个 BeanPostProcessorChecker,用于在 BeanPostProcessor 实例化期间创建 bean 时记录信息。
	// 如果一个 bean 不能被所有 BeanPostProcessor 处理,它会在这个检查器中进行标记。
	int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
	beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

	// 区分实现 PriorityOrdered、Ordered 和其它类型 BeanPostProcessor 的实例
	List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
	List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
	List<String> orderedPostProcessorNames = new ArrayList<>();
	List<String> nonOrderedPostProcessorNames = new ArrayList<>();
	for (String ppName : postProcessorNames) {
		if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
			BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
			priorityOrderedPostProcessors.add(pp);
			if (pp instanceof MergedBeanDefinitionPostProcessor) {
				internalPostProcessors.add(pp);
			}
		}
		else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
			orderedPostProcessorNames.add(ppName);
		}
		else {
			nonOrderedPostProcessorNames.add(ppName);
		}
	}

	// 首先,注册实现 PriorityOrdered 接口的 BeanPostProcessor 实例。
	sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
	registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

	// 接下来,注册实现 Ordered 接口的 BeanPostProcessor 实例。
	List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>();
	for (String ppName : orderedPostProcessorNames) {
		BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
		orderedPostProcessors.add(pp);
		if (pp instanceof MergedBeanDefinitionPostProcessor) {
			internalPostProcessors.add(pp);
		}
	}
	sortPostProcessors(orderedPostProcessors, beanFactory);
	registerBeanPostProcessors(beanFactory, orderedPostProcessors);

	// 现在,注册所有普通的 BeanPostProcessor 实例。
	List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
	for (String ppName : nonOrderedPostProcessorNames) {
		BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
		nonOrderedPostProcessors.add(pp);
		if (pp instanceof MergedBeanDefinitionPostProcessor) {
			internalPostProcessors.add(pp);
		}
	}
	registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

	// 最后,重新注册所有内部的 BeanPostProcessor 实例。
	sortPostProcessors(internalPostProcessors, beanFactory);
	registerBeanPostProcessors(beanFactory, internalPostProcessors);

	// 重新注册用于检测内部 bean 的后处理器作为 ApplicationListeners,并将其移动到处理器链的末尾(用于拾取代理等)。
	beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}

initMessageSource()

为上下文初始化Message源,即不同语言的消息体,国际化处理

这里的作用很明显就是提取配置中定义的MessageSource,并将其记录在Spring容器中。如果用户没有设置资源文件,Spring提供了默认的配置 DelegatingMessageSource。
在这里Spring 通过 beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class); 来获取名称为 MESSAGE_SOURCE_BEAN_NAME (messageSource) 的bean作为 资源文件。这里也体现出了Spring “约束大于规定”的原则。
在这里插入图片描述

initApplicationEventMulticaster()

初始化应用消息广播器,并放入"applicationEventMulticaster" bean 中,方便后续发布监听事件
initApplicationEventMulticaster 存在两种:

  1. 默认的事件广播器 ApplicationEventMulticaster
  2. 用户自定义的事件广播器

注意:
如果用户自定义了事件广播器,在使用用户自定义的事件广播器。
如果用户没有自定义事件广播器,则使用默认的 ApplicationEventMulticaster
在这里插入图片描述
在 SimpleApplicationEventMulticaster 中multicastEvent方法,可以看到,当Spring事件产生的时候,默认会使用multicastEvent 方法来广播事件,遍历给定事件类型的所有注册监听器,并使用监听器中的 onApplicationEvent 方法来进行监听事件的处理(通过 invokeListener 方法激活监听方法onApplicationEvent)。而对于每个监听器来说,其实都可以获取到产生的事件,但使用进行处理由监听器自己决定。

@Override
public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
    // 如果未提供事件类型,则解析事件类型
    ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));

    // 遍历给定事件类型的所有注册监听器
    for (final ApplicationListener<?> listener : getApplicationListeners(event, type)) {
        // 获取用于异步事件处理的任务执行器
        Executor executor = getTaskExecutor();

        // 如果存在任务执行器,则在单独的线程上执行监听器
        if (executor != null) {
            executor.execute(() -> invokeListener(listener, event));
        } else {
            // 如果没有任务执行器,则同步调用监听器
            invokeListener(listener, event);
        }
    }
}

// 辅助方法,用于调用监听器,并处理错误(如果设置了ErrorHandler)
protected void invokeListener(ApplicationListener<?> listener, ApplicationEvent event) {
    ErrorHandler errorHandler = getErrorHandler();

    // 如果设置了ErrorHandler,则在try-catch块内调用监听器
    if (errorHandler != null) {
        try {
            doInvokeListener(listener, event);
        } catch (Throwable err) {
            // 使用指定的ErrorHandler处理错误
            errorHandler.handleError(err);
        }
    } else {
        // 如果未设置ErrorHandler,则在不处理错误的情况下调用监听器
        doInvokeListener(listener, event);
    }
}

// 实际调用监听器的onApplicationEvent方法
@SuppressWarnings({"unchecked", "rawtypes"})
private void doInvokeListener(ApplicationListener listener, ApplicationEvent event) {
    try {
        // 调用监听器的onApplicationEvent方法
        listener.onApplicationEvent(event);
    } catch (ClassCastException ex) {
        // 处理ClassCastException,可能由未解析的泛型事件类型导致
        String msg = ex.getMessage();
        if (msg == null || matchesClassCastMessage(msg, event.getClass())) {
            // 抑制异常,并记录非匹配事件类型的调试信息
            Log logger = LogFactory.getLog(getClass());
           	if (logger.isDebugEnabled()) {
					logger.debug("Non-matching event type for listener: " + listener, ex);
				}
			}
			else {
				throw ex;
			}
		}
	}

onRefresh()

Initialize other special beans in specific context subclasses.
初始化特定上下文子类中的其他特殊bean。
在这里插入图片描述

registerListeners()

注册监听器,实例化之前要把我们的监听器,监听事件注册好。

/**
 * 将实现了 ApplicationListener 接口的 Bean 添加为监听器。
 * 不会影响其他非Bean的监听器的添加。
 */
protected void registerListeners() {
    // 首先注册静态指定的监听器。
    for (ApplicationListener<?> listener : getApplicationListeners()) {
        getApplicationEventMulticaster().addApplicationListener(listener);
    }

    // 在这里不要初始化 FactoryBeans:我们需要保持所有常规 Bean 未初始化,以便让后置处理器对它们应用。
    String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
    for (String listenerBeanName : listenerBeanNames) {
        getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
    }

    // 现在我们终于有了一个多播器,可以发布早期应用程序事件了...
    Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
    this.earlyApplicationEvents = null;
    if (earlyEventsToProcess != null) {
        for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
            getApplicationEventMulticaster().multicastEvent(earlyEvent);
        }
    }
}
  1. 注册静态指定的监听器:
    首先,方法通过 getApplicationListeners() 获取所有在配置中静态指定的监听器。
    然后,通过 addApplicationListener 将这些监听器添加到应用事件广播器(ApplicationEventMulticaster)中。

  2. 注册实现了 ApplicationListener 接口的 Bean
    接下来,方法通过 getBeanNamesForType 获取所有实现了 ApplicationListener 接口的 Bean 的名称
    然后,通过 addApplicationListenerBean 将这些 Bean 添加到应用事件广播器中。这样做的目的是让通过Spring容器管理的Bean成为应用程序的监听器。

  3. 发布早期应用程序事件
    最后,如果存在早期应用程序事件(earlyApplicationEvents),则通过 multicastEvent 方法发布这些事件
    这样做是为了确保在应用程序上下文初始化的早期阶段,已经产生的事件能够被监听器接收和处理。

总体来说,registerListeners() 方法的目的是将各种类型的监听器注册到应用事件广播器中,以便它们能够接收和处理应用程序中产生的事件。

finishBeanFactoryInitialization()

实例化剩下的非懒加载的单例
在这里插入图片描述

/**
 * 完成此上下文的Bean工厂的初始化,初始化所有剩余的单例Bean。
 */
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
    // 为此上下文初始化转换服务。
    if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
            beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
        beanFactory.setConversionService(
                beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
    }

    // 如果没有Bean后置处理器(如PropertyPlaceholderConfigurer Bean)在之前注册任何嵌入值解析器,
    // 则注册一个默认的嵌入值解析器:主要用于解析注解属性值。
    if (!beanFactory.hasEmbeddedValueResolver()) {
        beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
    }

    // 提前初始化LoadTimeWeaverAware Bean,以便尽早注册它们的转换器。
    String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
    for (String weaverAwareName : weaverAwareNames) {
        getBean(weaverAwareName);
    }

    // 停止使用临时类加载器进行类型匹配。
    beanFactory.setTempClassLoader(null);

    // 允许缓存所有Bean定义元数据,不再期望进一步的更改。
    beanFactory.freezeConfiguration();

    // 实例化所有剩余的(非延迟初始化)单例Bean。
    beanFactory.preInstantiateSingletons();
}

该方法的作用是完成Bean工厂的初始化,初始化所有剩余的单例Bean

  1. 初始化转换服务:如果Bean工厂中包含名为 CONVERSION_SERVICE_BEAN_NAME 的Bean,并且该Bean的类型是 ConversionService,则将其设置为Bean工厂的转换服务。

  2. 注册默认的嵌入值解析器:如果Bean工厂没有注册任何嵌入值解析器(embedded value resolver),则注册一个默认的嵌入值解析器。这个解析器主要用于解析注解属性值中的占位符。

  3. 提前初始化LoadTimeWeaverAware Bean:提前初始化实现了 LoadTimeWeaverAware 接口的Bean,以便尽早注册它们的转换器(transformers)。

  4. 停止使用临时类加载器进行类型匹配:停止使用临时类加载器(tempClassLoader)进行Bean的类型匹配。

  5. 允许缓存所有Bean定义元数据:允许缓存所有Bean定义的元数据,表示不再期望对Bean定义进行进一步的更改。

  6. 实例化所有剩余的单例Bean:实例化所有剩余的非延迟初始化的单例Bean。
    在这里插入图片描述

总体来说,finishBeanFactoryInitialization() 方法的目的是在Bean工厂初始化过程的最后阶段完成剩余单例Bean的初始化工作。

finishRefresh()

	/**
	 * Finish the refresh of this context, invoking the LifecycleProcessor's
	 * onRefresh() method and publishing the
	 * {@link org.springframework.context.event.ContextRefreshedEvent}.
	 */
	protected void finishRefresh() {
		// Clear context-level resource caches (such as ASM metadata from scanning).
		clearResourceCaches();

		// Initialize lifecycle processor for this context.
		initLifecycleProcessor();

		// Propagate refresh to lifecycle processor first.
		getLifecycleProcessor().onRefresh();

		// Publish the final event.
		publishEvent(new ContextRefreshedEvent(this));

		// Participate in LiveBeansView MBean, if active.
		LiveBeansView.registerApplicationContext(this);
	}

总结

提示:这里对文章进行总结:
例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。

  • 28
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值