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();
}
  • 发布容器初始化完成通知

至此,容器初始化完毕。

相关推荐
0wioiw05 分钟前
Python基础(Flask①)
后端·python·flask
风象南33 分钟前
SpringBoot 自研运行时 SQL 调用树,3 分钟定位慢 SQL!
spring boot·后端
Jenny37 分钟前
第九篇:卷积神经网络(CNN)与图像处理
后端·面试
大志说编程39 分钟前
LangChain框架入门16:智能客服系统RAG应用实战
后端·langchain·aigc
沸腾_罗强1 小时前
Redis内存爆了
后端
天天摸鱼的java工程师1 小时前
Snowflake 雪花算法优缺点(Java老司机实战总结)
java·后端·面试
海梨花2 小时前
【从零开始学习Redis】项目实战-黑马点评D2
java·数据库·redis·后端·缓存
bug菌2 小时前
零基础也能做出AI应用?Trae是如何打破编程"高墙"的?
后端·ai编程·trae
Java技术小馆2 小时前
重构 Controller 的 7 个黄金法则
java·后端·面试