Spring 6 IOC container loading process and core method refresh source code analysis

Preface: This article only sorts out and analyzes the core logic of the main line. This article takes the AnnotationConfigApplicationContext container as an example to analyze [Spring version: v6.0.2]

1. Instantiate the container AnnotationConfigApplicationContext

When we started the container, although only a new AnnotationConfigApplicationContext object was created, spring handled a lot of things in the process.

Create an AnnotationConfigApplicationContext object

AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class);

The class structure diagram of AnnotationConfigApplicationContext is as follows:

insert image description here

Enter the parameterized constructor of the AnnotationConfigApplicationContext class

	/**
	 * Create a new AnnotationConfigApplicationContext, deriving bean definitions
	 * from the given component classes and automatically refreshing the context.
	 * @param componentClasses one or more component classes — for example,
	 * {@link Configuration @Configuration} classes
	 */
	public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
    
    
		// 调用无参构造函数
		this();
		// 注册配置类为BeadDefinition
		register(componentClasses);
		// IOC容器刷新
		refresh();
	}

1. this() parameterless construction method

The no-argument structure mainly instantiates the reader and the scanner . The reader is the bean definition reader responsible for the annotation type. The type of the scanner is ClassPathBeanDefinitionScanner. It just calls the .scan method manually outside, or Call the constructor whose parameter is String, and pass in the name of the package to be scanned before it will be used.

	/**
	 * Create a new AnnotationConfigApplicationContext that needs to be populated
	 * through {@link #register} calls and then manually {@linkplain #refresh refreshed}.
	 */
	// 调用本构造方法之前会先去调用父类GenericApplicationContext的构造函数
	public AnnotationConfigApplicationContext() {
    
    
		StartupStep createAnnotatedBeanDefReader = this.getApplicationStartup().start("spring.context.annotated-bean-reader.create");
		// 创建一个读取注解的Bean定义的读取器,完成了spring内部BeanDefinition的注册
		this.reader = new AnnotatedBeanDefinitionReader(this);
		createAnnotatedBeanDefReader.end();
		// 创建BeanDefinition扫描器,可以用来扫描包或者类,继而转换成bean定义
		// 注意:spring默认的扫描包不是这个scanner对象,而是自己new的一个ClassPathBeanDefinitionScanner
		this.scanner = new ClassPathBeanDefinitionScanner(this);
	}

2. Instantiate the Bean factory: DefaultListableBeanFactory

In the above source code, the constructor of the parent class is implicitly called, that is, the constructor of GenericApplicationContext is called. In this construction method, a beanFactory (DefaultListableBeanFactory) is created to produce and obtain Bean.

	/**
	 * Create a new GenericApplicationContext.
	 * @see #registerBeanDefinition
	 * @see #refresh
	 */
	public GenericApplicationContext() {
    
    
		// 为ApplicationContext spring上下文对象初始化beanFactory,
		// DefaultListableBeanFactory在顶级接口BeanFactory基础上扩展了更多的功能,比如它实现了BeanDefinitionRegistry接口,拥有注册bean定义的能力
		this.beanFactory = new DefaultListableBeanFactory();
	}

DefaultListableBeanFactory class structure diagram:

  • DefaultListableBeanFactory implements the BeanDefinationRegistry interface and has the ability to register bean definitions. The registration of the bean definition later is that this class is responsible for
    insert image description here

3. Instantiate the BeanDefinition reader: AnnotatedBeanDefinitionReader

	/**
	 * Create a new {@code AnnotatedBeanDefinitionReader} for the given registry,
	 * using the given {@link Environment}.
	 * @param registry the {@code BeanFactory} to load bean definitions into,
	 * in the form of a {@code BeanDefinitionRegistry}
	 * @param environment the {@code Environment} to use when evaluating bean definition
	 * profiles.
	 * @since 3.1
	 */
	public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
    
    
		Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
		Assert.notNull(environment, "Environment must not be null");
		// 把ApplicationContext对象的registry,赋值给AnnotatedBeanDefinitionReader
		this.registry = registry;
		// 处理条件注解 @Condition
		this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
		// 注册一些spring的内置后置处理器
		AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
	}

4. Create a BeanDefinition scanner: ClassPathBeanDefinitionScanner

Generally, the scanner in AnnotationConfigApplicationContext will not be used. The scanner here is only for programmers to manually call the scan method of the AnnotationConfigApplicationContext object.

AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.scan();

5. Register the configuration class as BeanDefinition: register(annotatedClasses)

Register is the method mentioned at the beginning. Let's analyze the register(annotatedClasses) method. Its main function is to register the configuration class as a bean definition.
insert image description here

	/**
	 * Register one or more component classes to be processed.
	 * <p>Note that {@link #refresh()} must be called in order for the context
	 * to fully process the new classes.
	 * @param componentClasses one or more component classes &mdash; for example,
	 * {@link Configuration @Configuration} classes
	 * @see #scan(String...)
	 * @see #refresh()
	 */
	@Override
	public void register(Class<?>... componentClasses) {
    
    
		Assert.notEmpty(componentClasses, "At least one component class must be specified");
		StartupStep registerComponentClass = this.getApplicationStartup().start("spring.context.component-classes.register")
				.tag("classes", () -> Arrays.toString(componentClasses));
		// 注册
		this.reader.register(componentClasses);
		registerComponentClass.end();
	}

Continue to go down and enter this.reader.register()the method

	/**
	 * Register one or more component classes to be processed.
	 * <p>Calls to {@code register} are idempotent; adding the same
	 * component class more than once has no additional effect.
	 * @param componentClasses one or more component classes,
	 * e.g. {@link Configuration @Configuration} classes
	 */
	public void register(Class<?>... componentClasses) {
    
    
		// 配置类可以传入多个,因此需要遍历注册
		for (Class<?> componentClass : componentClasses) {
    
    
			registerBean(componentClass);
		}
	}

Continue into registerBean()the method, and then into doRegisterBean()the method:

	/**
	 * Register a bean from the given bean class, deriving its metadata from
	 * class-declared annotations.
	 * @param beanClass the class of the bean
	 * @param name an explicit name for the bean
	 * @param qualifiers specific qualifier annotations to consider, if any,
	 * in addition to qualifiers at the bean class level
	 * @param supplier a callback for creating an instance of the bean
	 * (may be {@code null})
	 * @param customizers one or more callbacks for customizing the factory's
	 * {@link BeanDefinition}, e.g. setting a lazy-init or primary flag
	 * @since 5.0
	 */
	private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name,
			@Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier,
			@Nullable BeanDefinitionCustomizer[] customizers) {
    
    
		// 把传入的标记了注解的类转为AnnotatedGenericBeanDefinition数据结构,里面有一个getMetadata方法,可以拿到类上的注解
		AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
		// 判断是否需要跳过注解,spring中有一个@Condition注解,当不满足条件,这个bean就会跳过
		if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
    
    
			return;
		}

		abd.setInstanceSupplier(supplier);
		// 解析bean的作用域,如果没有配置,默认是单例
		ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
		abd.setScope(scopeMetadata.getScopeName());
		String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));

		// processCommonDefinitionAnnotations方法是解析通用注解,填充到AnnotatedGenericBeanDefinition,
		// 解析的注解为Lazy,Primary,DependsOn,Role,Description
		AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
		if (qualifiers != null) {
    
    
			for (Class<? extends Annotation> qualifier : qualifiers) {
    
    
				if (Primary.class == qualifier) {
    
    
					abd.setPrimary(true);
				}
				else if (Lazy.class == qualifier) {
    
    
					abd.setLazyInit(true);
				}
				else {
    
    
					abd.addQualifier(new AutowireCandidateQualifier(qualifier));
				}
			}
		}
		if (customizers != null) {
    
    
			for (BeanDefinitionCustomizer customizer : customizers) {
    
    
				customizer.customize(abd);
			}
		}

		// 存放BeanDefinition、bean的名字还有bean的别名信息
		BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
		definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
		
		// 注册,最终会调用DefaultListableBeanFactory中的registerBeanDefinition方法注册
		// DefaultListableBeanFactory会维护一系列的信息,比如beanDefinitionNames、beanDefinitionMap
		// beanDefinitionNames是一个List<String>,用于保存beanName, 最终将配置类的bean定义注册到beanDefinitionMap中
		BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
	}

6. The core method refresh()

In fact, before the refresh method is called, Spring has not yet scanned, but instantiated a factory, registered some built-in beans and the configuration class we passed in, and the most important process is completed in the refresh method.

Refresh source code display:

	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.
			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);

				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.
				registerBeanPostProcessors(beanFactory);
				beanPostProcess.end();

				// Initialize message source for this context.
				initMessageSource();

				// Initialize event multicaster for this context.
				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();
				contextRefresh.end();
			}
		}
	}

6.1、 prepareRefresh()

This method is used to prepare the container before refreshing, including setting the context state, obtaining properties, verifying necessary properties, etc. (The code in the core part has a Chinese description)

	/**
	 * Prepare this context for refreshing, setting its startup date and
	 * active flag as well as performing any initialization of property sources.
	 */
	protected void prepareRefresh() {
    
    
		// Switch to active.
		// 设置启动时间
		this.startupDate = System.currentTimeMillis();  
		this.closed.set(false);
		this.active.set(true);

		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...
		this.earlyApplicationEvents = new LinkedHashSet<>();
	}

Developers can implement the initPropertySources() method to add properties or set properties that need to be verified (when verifying properties, it will be verified whether there is a my-age configuration), as follows:

getEnvironment().setRequiredProperties("my-age");

6.2、obtainFreshBeanFactory()

This method gets a new beanFactory. The method is very simple, refresh BeanFactory and obtain getBeanFactory.

	/**
	 * Tell the subclass to refresh the internal bean factory.
	 * @return the fresh BeanFactory instance
	 * @see #refreshBeanFactory()
	 * @see #getBeanFactory()
	 */
	protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
    
    
		// 刷新 BeanFactory
		refreshBeanFactory();
		// 获取 getBeanFactory
		return getBeanFactory();
	}

6.3、prepareBeanFactory(beanFactory)

This method is used to configure standard beanFactory, set ClassLoader, set SpEL expression parser, add interface that ignores injection, add bean, add bean post-processor, etc.

	/**
	 * Configure the factory's standard context characteristics,
	 * such as the context's ClassLoader and post-processors.
	 * @param beanFactory the BeanFactory to configure
	 */
	protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    
    
		// Tell the internal bean factory to use the context's class loader etc.
		// 设置 beanFactory 的类加载器
		beanFactory.setBeanClassLoader(getClassLoader());
		// 设置支持表达式解析器
		beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
		// 为 beanFactory 增加了一个默认的 propertyEditor ,这个主要是对 bean 的属性等设置管理的一个工具
		beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

		// Configure the bean factory with context callbacks.
		// 添加部分BeanPostProcessor【ApplicationContextAwareProcessor】
		beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
		// 设置忽略的自动装配的接口EnvironmentAware、EmbeddedValueResolverAware、xxx
		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.
		beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

		// Detect a LoadTimeWeaver and prepare for weaving, if found.
		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());
		}
		// 注册应用程序启动bean名称
		if (!beanFactory.containsLocalBean(APPLICATION_STARTUP_BEAN_NAME)) {
    
    
			beanFactory.registerSingleton(APPLICATION_STARTUP_BEAN_NAME, getApplicationStartup());
		}
	}

6.4、postProcessBeanFactory(beanFactory)

At this point, all beanDefinitions have been loaded, but not yet instantiated to allow extended processing of the beanFactory in subclasses. For example, adding ware-related interface automatic assembly settings, adding post-processors, etc., is a method for subclasses to extend prepareBeanFactory(beanFactory).

6.5、invokeBeanFactoryPostProcessors(beanFactory)

Instantiate and call all registered beanFactory post-processors (beans that implement the interface BeanFactoryPostProcessor, executed after the beanFactory standard initialization).

	/**
	 * Instantiate and invoke all registered BeanFactoryPostProcessor beans,
	 * respecting explicit order if given.
	 * <p>Must be called before singleton instantiation.
	 */
	protected void invokeBeanFactoryPostProcessors(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(new LoadTimeWeaverAwareProcessor(beanFactory));
			beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
		}
	}
  • In the invokeBeanFactoryPostProcessors method, Spring will first find all BeanFactory post-processors that implement BeanDefinitionRegistryPostProcessor, then implement PriorityOrdered first, and then Ordered.

  • The most famous of these is ConfigurationClassPostProcessor, which is used to scan objects marked by @Component and @Bean, and register their BeanDefinition metadata to the BeanDefinitionMap of the Spring container. Then go to get all BeanFactory post-processors, remove the ones that have already been executed, and execute them in order according to the sorting. After this method ends, the BeanFactory post-processor has been registered and executed in the Spring context, and part of the BeanDefinition has also been registered.

6.6. Register Bean post-processors: registerBeanPostProcessors(beanFactory)

Register Bean post-processors, obtain the names of all Bean post-processors, and classify Bean post-processors. After the classification is performed, all priorityOrderedPostProcessors will become a Bean and enter the Spring container. Since the source code is quite messy, only the key parts of the code are sorted out here:

		// 1.获取所有的 Bean 后置处理器的名字
		String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

		// Register BeanPostProcessorChecker that logs an info message when
		// a bean is created during BeanPostProcessor instantiation, i.e. when
		// a bean is not eligible for getting processed by all BeanPostProcessors.
		int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
		beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
		
		// 2.对 Bean 后置处理器分类
		List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
		List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
		List<String> orderedPostProcessorNames = new ArrayList<>();
		List<String> nonOrderedPostProcessorNames = new ArrayList<>();
		
		...

		// First, register the BeanPostProcessors that implement PriorityOrdered.
		sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
		// 3.注册 Bean 后置处理器
		registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
		sortPostProcessors(orderedPostProcessors, beanFactory);
		registerBeanPostProcessors(beanFactory, orderedPostProcessors);
		registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
		// Finally, re-register all internal BeanPostProcessors.
		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));

6.7. Internationalization processing: initMessageSource()

Initializes the Message source for the context, and internationalizes message bodies in different languages.

6.8. Initialize the event broadcaster: initApplicationEventMulticaster()

	/**
	 * Initialize the ApplicationEventMulticaster.
	 * Uses SimpleApplicationEventMulticaster if none defined in the context.
	 * @see org.springframework.context.event.SimpleApplicationEventMulticaster
	 */
	protected void initApplicationEventMulticaster() {
    
    
		ConfigurableListableBeanFactory beanFactory = getBeanFactory();
		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 {
    
    
			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() + "]");
			}
		}
	}

6.9. Register listener: registerListeners()

	/**
	 * Add beans that implement ApplicationListener as listeners.
	 * Doesn't affect other listeners, which can be added without being beans.
	 */
	protected void registerListeners() {
    
    
	
		// 1. 添加指定的监听器
		for (ApplicationListener<?> listener : getApplicationListeners()) {
    
    
			getApplicationEventMulticaster().addApplicationListener(listener);
		}

		// 2. 获取所有实现 ApplicationListener 的广播器,并添加
		String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
		for (String listenerBeanName : listenerBeanNames) {
    
    
			getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
		}

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

6.10、finishBeanFactoryInitialization(beanFactory)

Instantiate all remaining non-lazy loaded singletons, such as the classes parsed according to various annotations in the invokeBeanFactoryPostProcessors method, will be initialized at this time. The process of instantiation of various BeanPostProcessor begins to work.

		// 1. 冻结所有的 bean,已经注册的 bean 定义将不会被修改或任何进一步的处理
		beanFactory.freezeConfiguration();

		// 2. 实例化所有剩余的非懒加载的 bean
		beanFactory.preInstantiateSingletons();
// 获取容器中所有 beanDefinition 的名称
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

for (String beanName : beanNames) {
    
    
	// 根据 beanName 获取 BeanDefinition
	RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
	// 不是抽象的 && 是单例的 && 不是懒加载的
	if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
    
    
		if (isFactoryBean(beanName)) {
    
    
			// 如果是 FactoryBean,就先获取 FactoryBean 实例
			Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
			if (bean instanceof SmartFactoryBean<?> smartFactoryBean && smartFactoryBean.isEagerInit()) {
    
    
				getBean(beanName);
			}
		}
		else {
    
    
			// 如果不是 FactoryBean,就直接获取 Bean
			getBean(beanName);
		}
	}
}

6.11、finishRefresh()

Clear the context resource cache (such as the ASM metadata in the scan), initialize the life cycle processor of the context, and refresh it, and publish the ContextRefreshedEvent event to inform the corresponding ApplicationListener to respond

	protected void finishRefresh() {
    
    
		// Clear context-level resource caches (such as ASM metadata from scanning).
		// 清除上下文资源缓存(如扫描中的ASM元数据) scanning).
		clearResourceCaches();

		// Initialize lifecycle processor for this context.
		// 初始化上下文的生命周期处理器,并刷新(找出Spring容器中实现了Lifecycle接口的bean并执行start()方法)
		initLifecycleProcessor();

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

		// Publish the final event.
		// 发布ContextRefreshedEvent事件告知对应的ApplicationListener进行响应的操作
		publishEvent(new ContextRefreshedEvent(this));
	}

The above is the Spring 6 IOC container loading process and the core method refresh source code analysis process, I hope it will be helpful to you.

Guess you like

Origin blog.csdn.net/qq_40436854/article/details/129889039