Spring 5.3.x 源码:refresh()方法

refresh()方法概述

本文参考的实现类是:AnnotationConfigApplicationContext上下文对应的refresh()方法。实际调用的是抽象类AbstractApplicationContext内编写的refresh()方法。

refresh()会通过一系列的配置完成spring容器的初始化,并且完成非惰性单例类的创建。

java 复制代码
public void refresh() throws BeansException, IllegalStateException {
    // 加锁
    synchronized (this.startupShutdownMonitor) {
        // 标记代码流程的开始和结束,这里开始后面还有结束,也就是日志(旧版本的源码可能没有这段代码)
        StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");

        // Prepare this context for refreshing.
        // 配置刷新上下文,设置一些状态,参数,给后续配置使用
        prepareRefresh();

        // Tell the subclass to refresh the internal bean factory.
        // 初始化类工厂,读取xml配置 默认的类工厂类型是:DefaultListableBeanFactory
        // 如果上下文是AbstractXmlApplicationContext的实现类,如:ClassPathXmlApplicationContext,这里还会读取xml的配置
        // 此时获得工厂类是全部值处于默认状态
        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

        // Prepare the bean factory for use in this context.
        // 真正构建类工厂的方法
        prepareBeanFactory(beanFactory);

        try {
            // Allows post-processing of the bean factory in context subclasses.
            // 为子类提供的类工厂自定义处理,在这个方法可以实现自定义的类工厂设置,默认没有实现
            postProcessBeanFactory(beanFactory);

            // 日志标签,标记spring.context.beans.post-process业务的开始
            StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");

            // Invoke factory processors registered as beans in the context.
            // 激活类工厂的后置处理器,为类工厂拓展功能
            invokeBeanFactoryPostProcessors(beanFactory);

            // Register bean processors that intercept bean creation.
            // 注册用于处理bean创建的后置处理器的处理器
            registerBeanPostProcessors(beanFactory);

            // 日志标签,标记spring.context.beans.post-process业务的结束
            beanPostProcess.end();

            // 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.
            // 留给子类来初始化其他的bean,空方法
            onRefresh();

            // Check for listener beans and register them.
            // 在所有注册的bean中查找监听器类,并注册到消息广播器中
            registerListeners();

            // Instantiate all remaining (non-lazy-init) singletons.
            // 初始化剩下的单实例(非惰性)
            finishBeanFactoryInitialization(beanFactory);

            // Last step: publish corresponding event.
            // 完成刷新过程,通知生命周期处理器 lifecycleProcesseor  刷新过程,同时发出ContextRefreshEvent 通知。
            finishRefresh();
        }
        // ....省略其它代码
    }
}

实现流程如下:

  1. prepareRefresh:配置刷新上下文,设置一些状态,参数,给后续配置使用
  2. obtainFreshBeanFactory:初始化类工厂,读取xml配置 默认的类工厂类型是:DefaultListableBeanFactory
    1. 如果上下文是AbstractXmlApplicationContext的实现类,如:ClassPathXmlApplicationContext,这里还会读取xml的配置
    2. 此时获得工厂类是全部值处于默认状态
  3. prepareBeanFactory:真正构建类工厂的方法,为类工厂添加各种配置
  4. postProcessBeanFactory:为子类提供的类工厂自定义处理,在这个方法可以实现自定义的类工厂设置,默认没有实现。
  5. invokeBeanFactoryPostProcessors:激活类工厂的后置处理器,为类工厂拓展功能
  6. registerBeanPostProcessors:注册用于处理bean创建的后置处理器的处理器
  7. initMessageSource:为上下文初始化Message源,即不同语言的消息体,国际化处理
  8. initApplicationEventMulticaster:初始化应用消息广播器,并放入applicationEventMulticaster bean
  9. onRefresh:留给子类来初始化其他的bean,空方法
  10. registerListeners :在所有注册的bean中查找listener bean,注册到消息广播器中
  11. finishBeanFactoryInitialization :初始化剩下的实例(非惰性),在这里调用了 **getBean**方法,创建了非惰性的 **bean**实例
  12. finishRefresh :完成刷新过程,通知生命周期处理器 lifecycleProcesseor 刷新过程,同时发出ContextRefreshEvent 通知容器的使用者。

refresh()详细分析

准备刷新-postProcessBeanFactory(beanFactory);

该方法主要设置一些启动信息,以及初始化两个列表。

java 复制代码
protected void prepareRefresh() {
    // Switch to active.
    // 记录启动时间
    this.startupDate = System.currentTimeMillis();
    // 关闭状态设置为false
    this.closed.set(false);
    // 激活状态设置为true
    this.active.set(true);
    // 是否开启debug日志
    if (logger.isDebugEnabled()) {
        if (logger.isTraceEnabled()) {
            logger.trace("Refreshing " + this);
        }
        else {
            logger.debug("Refreshing " + getDisplayName());
        }
    }

    // Initialize any placeholder property sources in the context environment.
    // 预留空方法,给子类实现,这里啥也不做,可以用来自定义参数
    initPropertySources();

    // Validate that all properties marked as required are resolvable:
    // see ConfigurablePropertyResolver#setRequiredProperties
    // 验证需要的属性文件是否都已经放入环境中,默认情况下是空的
    getEnvironment().validateRequiredProperties();

    // Store pre-refresh ApplicationListeners...
    // 初始化自定义的预刷新监听器,默认是空的
    if (this.earlyApplicationListeners == null) {
        this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
    }
    else {
        // Reset local application listeners to pre-refresh state.
        // 项目热更新时,如果监听器列表不为空,则清空再添加
        this.applicationListeners.clear();
        this.applicationListeners.addAll(this.earlyApplicationListeners);
    }

    // Allow for the collection of early ApplicationEvents,
    // to be published once the multicaster is available...
    // 初始化ApplicationEvents集合
    this.earlyApplicationEvents = new LinkedHashSet<>();
}

注意两个没有默认设置的方法

  • initPropertySources():这个方法是为了给程序员实现自定义的初始化逻辑,可以初始化一些属性资源。Spring并没有实现这个方法。
    • 用处:可以从这个方法总获取到this上下文,从而对上下文进行一些额外的配置
  • validateRequiredProperties():验证需要的属性文件是否都已经放入环境中,默认情况下是空的,没有具体的实现。
    • 用处:可以通过此方法来对getEnvironment()获取的环境变量中的参数进行验证和其它处理。

我们可以通过实现或者继承 ApplicationContext 来重写这两个方法,从而完成一些基本属性的校验。

初始化BeanFactory-obtainFreshBeanFactory()

英文翻译:获取新的类工厂但是这里只是初始化了默认的类工厂,并没有对其进行详细的配置


java 复制代码
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
    refreshBeanFactory();
    return getBeanFactory();
}

从上述代码可以看出,真正初始化的方法是refreshBeanFactory(),而refreshBeanFactory() 方法被两个类实现,使用不同的上下文对象,会使用不同的实现

  • AbstractRefreshableApplicationContext :这个的实现功能会比较多,比如读取xml硬编码的配置需要使用此类的实现类作为上下文。
  • GenericApplicationContext:这个则是基础实现

我们这里分析的是 GenericApplicationContext 实现。


GenericApplicationContext.refreshBeanFactory() 的实现如下:

java 复制代码
protected final void refreshBeanFactory() throws IllegalStateException {
    // 判断其他线程是否已经开始初始化类工厂,并且通过CAS 设置将刷新状态置为 true
    if (!this.refreshed.compareAndSet(false, true)) {
        throw new IllegalStateException(
            "GenericApplicationContext does not support multiple refresh attempts: just call 'refresh' once");
    }
    // 设置序列化id
    this.beanFactory.setSerializationId(getId());
}

注意点: **this.beanFactory**是何时创建的,为什么能设置 **SerializationId**

原因:AnnotationConfigApplicationContext继承了GenericApplicationContext 类,通过子类调用GenericApplicationContext的无参构造器初始化了this.beanFactory,如下:

java 复制代码
public GenericApplicationContext() {
    this.beanFactory = new DefaultListableBeanFactory();
}

实现过程十分简单,并且可以知道当 AnnotationConfigApplicationContext实例创建时, beanFactory就已经初始化完毕了。

配置BeanFactory-prepareBeanFactory()

obtainFreshBeanFactory()获取的是初始化状态的类工厂,而prepareBeanFactory()才是真正为类工厂完善配置的方法,对初始化的类工厂做许多配置。

java 复制代码
/**
* 配置类工厂的上下文信息
*/
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
	// Tell the internal bean factory to use the context's class loader etc.
	beanFactory.setBeanClassLoader(getClassLoader());
	// 默认是添加的,shouldIgnoreSpel值默认为true
	if (!shouldIgnoreSpel) {
		// 创建SpEL语言解析器,并赋值给beanFactory
		beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
	}
	// 为beanFactory 赋予环境变量和当前上下文,构建了一个资源编译器,主要用来需要时读取环境变量的信息
	// this就是当前上下文,
	// getEnvironment主要获取运行环境的配置信息(包含系统参数和jvm参数)
	beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
	
	// Configure the bean factory with context callbacks.
	// 配置Bean后置处理器
	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.ignoreDependencyInterface(ApplicationStartupAware.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.
	// 初步注册检测实现ApplicationListeners接口类的检测器
	beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
	
	// Detect a LoadTimeWeaver and prepare for weaving, if found.
	// 增加对 AspectJ的支持
	if (!NativeDetector.inNativeImage() && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
		beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
		// Set a temporary ClassLoader for type matching.
		beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
	}
	
	// Register default environment beans.
	// 配置默认的环境信息
	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());
	}
	if (!beanFactory.containsLocalBean(APPLICATION_STARTUP_BEAN_NAME)) {
		beanFactory.registerSingleton(APPLICATION_STARTUP_BEAN_NAME, getApplicationStartup());
	}
}

上述代码主要对几个方面进行了扩展:

  • 增加SpEL语言的支持
  • 增加对属性编辑器的支持,为beanFactory赋予环境变量和当前上下文,构建了一个资源编译器,主要用来需要时读取环境变量的信息
  • 增加了一些内置类,比如 EmbeddedValueResolver<font style="color:rgba(0, 0, 0, 0.75);">EnvironmentAware</font>等。
  • 配置了几个忽略自动装配的接口
  • 配置了几个自动装配的特殊规则
  • 增加 AspectJ 的支持
  • 将相关环境变量及属性以单例模式注册进类工厂

预留子类拓展的方法-postProcessBeanFactory()

AbstractApplicationContext并未对该方法做任何的实现,如下:

java 复制代码
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {

}

其子类可以通过重载该方法对BeanFactory进行自定义的配置。

激活BeanFactory的后置处理器-invokeBeanFactoryPostProcessors()

这个方法主要是处理BeanFactoryPostProcessors接口的实现类,以及对应的子接口BeanDefinitionRegistryPostProcessor的实现类。类图如下:

由于代码量比较大,这里就不展开说明了。请看[invokeBeanFactoryPostProcessors()详解](Spring 5.3.x 源码:invokeBeanFactoryPostProcessors()详解)。

注册BeanPostProcessor-registerBeanPostProcessors()

invokeBeanFactoryPostProcessorsregisterBeanPostProcessors实现方式基本上一样,不过前者是注册进BeanFactory并执行,而registerBeanPostProcessors只负责注册,但不执行。

java 复制代码
public static void registerBeanPostProcessors(
	ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {

	// 获取类工厂中加载好的所有BeanPostProcessor的子类
	String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

	// BeanPostProcessorChecker 是一个普通的信息打印
	//可能会有些情况当Spring 的配置中的后处理器还没有被注册就已经开始了bean的实例化,便会打印出BeanPostProcessorChecker 中设定的信息
	int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
	beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));


	// 保存实现了Priority和Orderd 接口的后置处理器
	List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
	// 保存MergedBeanDefinitionPostProcessor后置处理器
	List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
	// 保存实现了Orderd 接口的后置处理器
	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);
		}
	}

	// 对实现了PriorityOrderd 接口的后置处理器进行排序
	sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
	// 注册,实际上就是保存到 AbstractBeanFactory#beanPostProcessors 集合中。在getBean使用的时候直接拿取该属性即可
	registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

	// 以下代码类型
	// 处理Orderd的BeanPostProcessor
	List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
	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<>(nonOrderedPostProcessorNames.size());
	for (String ppName : nonOrderedPostProcessorNames) {
		BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
		nonOrderedPostProcessors.add(pp);
		if (pp instanceof MergedBeanDefinitionPostProcessor) {
			internalPostProcessors.add(pp);
		}
	}
	registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

	// Finally, re-register all internal BeanPostProcessors.
	// 这里并不是重复注册, registerBeanPostProcessors 方法会先移除已存在的 BeanPostProcessor 随后重新加入。
	sortPostProcessors(internalPostProcessors, beanFactory);
	registerBeanPostProcessors(beanFactory, internalPostProcessors);

	// Re-register post-processor for detecting inner beans as ApplicationListeners,
	// moving it to the end of the processor chain (for picking up proxies etc).
	beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}

接下看注册方法实现

java 复制代码
private static void registerBeanPostProcessors(
	ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) {

	if (beanFactory instanceof AbstractBeanFactory) {
		((AbstractBeanFactory) beanFactory).addBeanPostProcessors(postProcessors);
	}
	else {
		for (BeanPostProcessor postProcessor : postProcessors) {
			beanFactory.addBeanPostProcessor(postProcessor);
		}
	}
}

public void addBeanPostProcessors(Collection<? extends BeanPostProcessor> beanPostProcessors) {
	synchronized (this.beanPostProcessors) {
		// Remove from old position, if any
		// 删除重复的BeanPostProcessor
		this.beanPostProcessors.removeAll(beanPostProcessors);
		// Add to end of list
		// 然后将传进来的BeanPostProcessor插入到列表最末尾
		this.beanPostProcessors.addAll(beanPostProcessors);
	}
}

所以,从上述代码可以看出BeanPostProcessor是创建好并执行缓存起来了,供后续创建实例时候调用。

初始化消息资源-initMessageSource()

配置spring的信息资源,提供自定义和默认实现。

其中自定义实现的注入bean的类名必须是messageSource,硬编码约束在代码中;

如果没有自定义源则使用DelegatingMessageSource作为默认源,这是一个空实现,作用就是一个占位用的。

java 复制代码
protected void initMessageSource() {
	ConfigurableListableBeanFactory beanFactory = getBeanFactory();
	// 当用户自定义消息源配置是,类名必须是messageSource,否则读取不到,属于是硬编码约束
	if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
		this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
		// Make MessageSource aware of parent MessageSource.
		if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
			HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
			if (hms.getParentMessageSource() == null) {
				// Only set parent context as parent MessageSource if no parent MessageSource
				// registered already.
				hms.setParentMessageSource(getInternalParentMessageSource());
			}
		}
		if (logger.isTraceEnabled()) {
			logger.trace("Using MessageSource [" + this.messageSource + "]");
		}
	}
	else {
		// 如果没有自定义资源则使用DelegatingMessageSource,作为默认资源
		// Use empty MessageSource to be able to accept getMessage calls.
		DelegatingMessageSource dms = new DelegatingMessageSource();
		dms.setParentMessageSource(getInternalParentMessageSource());
		this.messageSource = dms;
		beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
		if (logger.isTraceEnabled()) {
			logger.trace("No '" + MESSAGE_SOURCE_BEAN_NAME + "' bean, using [" + this.messageSource + "]");
		}
	}
}

初始化事件监听-initApplicationEventMulticaster()

初始化方式类似initMessageSource(),自定义的事件监听器类名必须为applicationEventMulticaster,否则读取不到。

同时也提供了自定义和默认的实现。

java 复制代码
protected void initApplicationEventMulticaster() {
	ConfigurableListableBeanFactory beanFactory = getBeanFactory();
	// 获取类工厂中名为applicationEventMulticaster的类作为自定义的监听器,属于硬编码指定类名
	if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
		this.applicationEventMulticaster =
		beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
		if (logger.isTraceEnabled()) {
			logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
		}
	}
	else {
		// 如果没有则使用默认的SimpleApplicationEventMulticaster监听器
		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() + "]");
		}
	}
}

SimpleApplicationEventMulticaster 中有一段代码如下,可以看到,当Spring事件产生的时候,默认会使用SimpleApplicationEventMulticaster#multicastEvent方法来广播事件,遍历所有的监听器,并使用监听器中的 onApplicationEvent 方法来进行监听事件的处理(通过 invokeListener 方法激活监听方法)。而对于每个监听器来说,都可以获取到产生的事件,但是否对事件进行处理,则由收到事件的监听器自己决定。

java 复制代码
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);
		}
	}
}

预留的钩子-onRefresh()

这里spring没有做任何实现,给子类拓展用的。

注册监听器-registerListeners()

实现逻辑如下:

  • 优先加载spring中定义好的监听器(硬编码)
  • 其次加载通过类工厂注入的监听器(动态添加)
  • 给所有监听器发送预先保存好的消息,初步处理由每个监听器决定
java 复制代码
protected void registerListeners() {
	
	// 注册所有的静态(硬编码)的监听器
	for (ApplicationListener<?> listener : getApplicationListeners()) {
		getApplicationEventMulticaster().addApplicationListener(listener);
	}

	// 从类工厂中获取所有ApplicationListener的实现类,这里属于动态添加,上面是静态写死的监听器
	String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
	for (String listenerBeanName : listenerBeanNames) {
		getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
	}

	// 发布之前保存的需要发布的事件
	Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
	this.earlyApplicationEvents = null;
	if (!CollectionUtils.isEmpty(earlyEventsToProcess)) {
		for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
			//这里获取的广播器在前面的流程中已经实现注册
			getApplicationEventMulticaster().multicastEvent(earlyEvent);
		}
	}
}

完成BeanFactory的初始化-finishBeanFactoryInitialization()

实现功能如下:

  • 初始化conversion service,这是一个用来做类型转换的工具类
  • 冻结配置,说明这个类工厂已经加载完毕,不能再做任何修改也正式可以缓存bean的元数据了。
  • 初始化剩下的非惰性单实例。
    • ApplicationContext实现的默认行为就是启动时将所有单例bean提前进行实例化。
    • 提前实例化意味着作为初始化过程的一部分,ApplicationContext 实例会创建并配置所有的单例bean。而这个实例化的过程就是在 preInstantiateSingletons中完成的。
java 复制代码
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
	// 初始化conversion service,用来做类型转换的工具类
	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));
	}
	
	// Register a default embedded value resolver if no BeanFactoryPostProcessor
	// (such as a PropertySourcesPlaceholderConfigurer bean) registered any before:
	// at this point, primarily for resolution in annotation attribute values.
	//  不知道干嘛用的,语义就是增加了一个EmbeddedValueResolver
	if (!beanFactory.hasEmbeddedValueResolver()) {
		beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
	}
	
	// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
	// 初始化aop支持
	String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
	for (String weaverAwareName : weaverAwareNames) {
		getBean(weaverAwareName);
	}
	
	// Stop using the temporary ClassLoader for type matching.
	// 移除临时的类加载器
	beanFactory.setTempClassLoader(null);
	
	// Allow for caching all bean definition metadata, not expecting further changes.
	// 冻结配置,说明这个类工程已经加载完毕,不能再做任何修改
	beanFactory.freezeConfiguration();
	
	// Instantiate all remaining (non-lazy-init) singletons.
	// 创建所有剩余的非惰性的单例bean,惰性的单例只有在使用时才会创建
	beanFactory.preInstantiateSingletons();
}

beanFactory.preInstantiateSingletons()调用的是DefaultListableBeanFactorypreInstantiateSingletons方法。在这里面,容器创建了所有的非惰性单实例。(之所以不创建原型bean,是因为原型bean没必要进行缓存,每次使用直接创建即可)

java 复制代码
public void preInstantiateSingletons() throws BeansException {
	if (logger.isTraceEnabled()) {
		logger.trace("Pre-instantiating singletons in " + this);
	}
	
	// Iterate over a copy to allow for init methods which in turn register new bean definitions.
	// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
	// 获取所有注册进类工厂的类名
	List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
	
	// Trigger initialization of all non-lazy singleton beans...
	for (String beanName : beanNames) {
		// 获取类名对应的BeanDefinition
		RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
		// 非抽象 是单例 不是非惰性
		if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
			// 判断是否是  FactoryBean 类型
			if (isFactoryBean(beanName)) {
				// 如果是 Factory bean 则 拼接 & 前缀获取bean
				Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
				if (bean instanceof FactoryBean) {
					FactoryBean<?> factory = (FactoryBean<?>) bean;
					// 判断是否要立即初始化Bean。对于 FactoryBean,可能并不需要立即初始化其getObject 方法代理的对象。
					boolean isEagerInit; // 是否需要立即创建
					if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
						isEagerInit = AccessController.doPrivileged(
							(PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,
							getAccessControlContext());
					}
					else {
						isEagerInit = (factory instanceof SmartFactoryBean &&
									   ((SmartFactoryBean<?>) factory).isEagerInit());
					}
					// 如果需要立即初始化,则初始化bean
					if (isEagerInit) {
						getBean(beanName);
					}
				}
			}
			else {
				// 直接获取bean实例
				getBean(beanName);
			}
		}
	}
	
	// 触发所有适用bean的初始化后回调。 这里实际上是触发 SmartInitializingSingleton#afterSingletonsInstantiated 方法
	// Trigger post-initialization callback for all applicable beans...
	for (String beanName : beanNames) {
		Object singletonInstance = getSingleton(beanName);
		if (singletonInstance instanceof SmartInitializingSingleton) {
			StartupStep smartInitialize = getApplicationStartup().start("spring.beans.smart-initialize")
			.tag("beanName", beanName);
			SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
			if (System.getSecurityManager() != null) {
				AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
					smartSingleton.afterSingletonsInstantiated();
					return null;
				}, getAccessControlContext());
			}
			else {
				smartSingleton.afterSingletonsInstantiated();
			}
			smartInitialize.end();
		}
	}
}

完成刷新-finishRefresh()

实现如下:

  • 清除资源缓存
  • 初始化生命周期处理器LifecycleProcessor
  • 执行生命周期处理器的onRefresh方法
java 复制代码
public interface LifecycleProcessor extends Lifecycle {

    // 容器刷新完成时调用
    void onRefresh();


    // 容器关闭时调用
    void onClose();
}
  • 发布容器初始化完成通知

至此,容器初始化完毕。

相关推荐
幽络源小助理13 小时前
springboot校园车辆管理系统源码 – SpringBoot+Vue项目免费下载 | 幽络源
vue.js·spring boot·后端
刀法如飞13 小时前
一款开箱即用的Spring Boot 4 DDD工程脚手架
java·后端·架构
uzong14 小时前
后端系统设计文档模板
后端
幽络源小助理14 小时前
SpringBoot+Vue车票管理系统源码下载 – 幽络源免费项目实战代码
vue.js·spring boot·后端
uzong14 小时前
软件架构指南 Software Architecture Guide
后端
又是忙碌的一天14 小时前
SpringBoot 创建及登录、拦截器
java·spring boot·后端
勇哥java实战分享15 小时前
短信平台 Pro 版本 ,比开源版本更强大
后端
学历真的很重要15 小时前
LangChain V1.0 Context Engineering(上下文工程)详细指南
人工智能·后端·学习·语言模型·面试·职场和发展·langchain
计算机毕设VX:Fegn089515 小时前
计算机毕业设计|基于springboot + vue二手家电管理系统(源码+数据库+文档)
vue.js·spring boot·后端·课程设计
上进小菜猪16 小时前
基于 YOLOv8 的智能杂草检测识别实战 [目标检测完整源码]
后端