【Spring源码阅读】 preInstantiateSingletons方法分析,单例Bean获取/实例化流程

本文深入分析了Spring框架中`preInstantiateSingletons`方法的作用,该方法在`ClassPathXmlApplicatonContext`初始化时,用于实例化非懒加载的单例Bean。在此之前,已完成BeanFactory初始化、BeanDefinition解析和BeanPostProcessor注册等步骤。`getSingleton`在`DefaultSingletonBeanRegistry`中实现,而`createBean`方法在`AbstractAutowireCapableBeanFactory`中,负责Bean的实际创建。虽然依赖注入细节未展开讨论,但强调了大部分Bean通过`getSingleton`获取,并在缓存未命中时调用`createBean`创建。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在初始化ClassPathXmlApplicatonContext过程中,核心初始化逻辑在AbstractApplicationContext的refresh函数中:

public void refresh() throws BeansException, IllegalStateException {
   
   
	synchronized (this.startupShutdownMonitor) {
   
   
		// 供子类拓展,添加创建前必需属性,校验如果必需属性不存在则抛出MissingRequiredPropertiesException已成
		prepareRefresh();

		// 调用子类实现方法获取(创建或刷新)BeanFacotry容器,对于ClassPathXmlApplicationContext,主要调用了AbstractRefreshableApplicationContext中实现的方法
		// 在这里,将xml配置文件中 的Bean解析成了一个个BeanDefinition,建立一个beanName-> beanDefinition 的 map
		ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

		// 设定类加载器,spel解析器,属性编辑解析器等,忽略特定接口的依赖注册(在特定时刻相关Bean再完成注入),注册一些系统Bean供依赖注入使用。
		prepareBeanFactory(beanFactory);

		try {
   
   
			// BeanFactory创建完的后置处理。当前为空实现,供子类拓展
			postProcessBeanFactory(beanFactory);

			// 调用BeanFacotry的相关后置处理器,如果实现了Order相关接口,会先进行排序。
			invokeBeanFactoryPostProcessors(beanFactory);

			// 注册相关BeanPostProcessor,供Bean生成前后调用。
			registerBeanPostProcessors(beanFactory);

			// 初始化国际化信息源
			initMessageSource();

			// 初始化Spring相关上下文时间广播器
			initApplicationEventMulticaster();

			// 模版方法供子类实现,用于初始化一些特殊Bean配置等
			onRefresh();

			// 注册实现了ApplicationListener接口的事件监听器,用于后续广播器广播事件
			registerListeners();

			// BeanFactory初始化完成时调用,初始ConversionService Bean,冻结beanFactory配置,并开始创建BeanFactory中所有非懒加载的单例Bean
			finishBeanFactoryInitialization(beanFactory);

			// 初始化Lifecycle处理器,调用onRefresh方法,广播ContextRefreshedEvent。
			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;
		}
	}
}

其中有一行代码,调用了finishBeanFactoryInitialization(beanFactory)。在这一步之前,已经完成了BeanFactory对象初始化、xml配置文件解析成BeanDefinition、BeanPostProcessor初始化与注册等操作。
而在完成BeanFactory初始化之时,会初始化容器内所有单例非懒加载对象,供后续业务逻辑进行依赖注入等使用,具体实现在finishBeanFactoryInitialization(beanFactory)内部的最后一行代码:

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
   
   
	//…… 省略前面代码

	// 预实例化所有非懒加载单例Bean
	beanFactory.preInstantiateSingletons();
}

具体的preInstantiateSingletons实现如下:

public void preInstantiateSingletons() throws BeansException {
   
   
	if (this.logger.isInfoEnabled()) {
   
   
		this.logger.info("Pre-instantiating singletons in " + this);
	}

	List<String> beanNames;
	synchronized (this.beanDefinitionMap) {
   
   
		// 获取容器内加载的所有BeanDefinition
		beanNames = new ArrayList<String>(this.beanDefinitionNames);
	}

	// 遍历初始化所有非懒加载单例Bean
	for (String beanName : beanNames) {
   
   
	    // Bean定义公共的抽象类是AbstractBeanDefinition,普通的Bean在Spring加载Bean定义的时候,实例化出来的是GenericBeanDefinition
	    // 而Spring上下文包括实例化所有Bean用的AbstractBeanDefinition是RootBeanDefinition
	    // 这时候就使用getMergedLocalBeanDefinition方法做了一次转化,将非RootBeanDefinition转换为RootBeanDefinition以供后续操作。
	    // 注意如果当前BeanDefinition存在父BeanDefinition,会基于父BeanDefinition生成一个RootBeanDefinition,然后再将调用OverrideFrom子BeanDefinition的相关属性覆写进去。
		RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
		// 如果Bean不是抽象的,是单例的,不是懒加载的,则开始创建单例对象通过调用getBean(beanName)方法初始化
		if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
   
   
		    // 判断当前Bean是否实现了FactoryBean接口,如果实现了,判断是否要立即初始化
		    // 判断是否需要立即初始化,根据Bean是否实现了SmartFactoryBean并且重写的内部方法isEagerInit放回true
			if (isFactoryBean(beanName)) {
   
   
				final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
				boolean isEagerInit;
				if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
   
   
					isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
   
   
						public Boolean run() {
   
   
							return ((SmartFactoryBean<
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值