Spring源码分析--Bean的实例化

本文详细解析了Spring框架中Bean的实例化过程,包括BeanPostProcessor的调用时机,循环依赖处理,以及初始化和销毁流程。揭示了Spring如何通过后置处理器扩展Bean的生命周期。

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

三、Bean实例化

public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			// Prepare this context for refreshing.
			prepareRefresh();
 
			// Tell the subclass to refresh the internal bean factory.
			
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
			
			prepareBeanFactory(beanFactory);
 
			try {
				// Allows post-processing of the bean factory in context subclasses.
				
				postProcessBeanFactory(beanFactory);
 
				// Invoke factory processors registered as beans in the context.
				
				invokeBeanFactoryPostProcessors(beanFactory);
 
				// Register bean processors that intercept bean creation.
				registerBeanPostProcessors(beanFactory);
 
				// 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();
			}
		}
	}

6、registerBeanPostProcessors(beanFactory)

将容器中已经定义的实现了BeanPostProcessor接口的实现类按照特定的顺序注册到容器中,如注册拦截bean创建的后置处理器CommonAnnotationBeanPostProcessor AutowiredAnnotationBeanPostProcessor,还有一些自定义实现BeanPostProcessor接口都注册到容器中,并在后续创建bean的时候调用。

7、initMessageSource

初始化messageSource组件,用来做国际化,消息绑定,消息解析

8、initApplicationEventMulticaster()

向容器中注册基于事件开发的事件多播器对象

9、onrefresh()

空方法,留给子类继承实现个性换配置的

10、registerListeners()

将所有的监听器对象添加到多播器对象中,以便后续对事件的派发

11、finishBeanFactoryInitialization(beanFactory)

实例化所有剩余的(非懒加载)单例

在preInstantiateSingletons方法中会调用getBean去创建实例化bean。

我们着重看doGetBean方法,先从单例缓存中找,没有找到会先判断是否是正在创建的bean

Object sharedInstance = getSingleton(beanName);

protected Object getSingleton(String beanName, boolean allowEarlyReference) {
		// 先从单例缓存中找,没有找到会先判断是否是正在创建的bean
		// isSingletonCurrentlyInCreation 判断对应的单例对象是否在创建中
		Object singletonObject = this.singletonObjects.get(beanName);
		if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
			synchronized (this.singletonObjects) {
				// earlySingletonObjects中保存所有提前曝光的单例,尝试从earlySingletonObjects中找
				singletonObject = this.earlySingletonObjects.get(beanName);
				if (singletonObject == null && allowEarlyReference) {
					// 如果允许早期依赖,可以尝试从singletonFactories中找到对应的单例工厂
					ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
					if (singletonFactory != null) {
						//创建bean,并缓存提前曝光的bean,就是还未进行属性注入的bean,用于解决循环依赖
						singletonObject = singletonFactory.getObject();
						this.earlySingletonObjects.put(beanName, singletonObject);
						this.singletonFactories.remove(beanName);
					}
				}
			}
		}
		return singletonObject;
	}

然后会去判断bean = getObjectForBeanInstance(sharedInstance, name, beanName, null)是普通bean还是factoryBean,如果是factoryBean那么就调用FactoryBean的getObject()方法返回bean而不用去实例化。

object = factory.getObject()

需要去标注该bean正在被创建,防止多个线程同时创建名称相同的bean对象。 

if (!typeCheckOnly) {
// 标记 bean要创建了
markBeanAsCreated(beanName);
}

循环依赖问题:A有B的属性,而B有A的属性,那么getBean(A),获取到A的实例,此时还未进行注入;当开始注入,发现B属性,开始getBean(B),获取到B的实例;开始对B注入,发现A属性,这样就可以获取到还未注入完成的A。也就是在构建单例的时候,会将还未完成注入的A提前暴露,便于B完成注入。

这里就是依赖类的创建

if (dependsOn != null) {
	for (String dep : dependsOn) {
		if (isDependent(beanName, dep)) {
			throw new BeanCreationException(mbd.getResourceDescription(), beanName,
									"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
						}
		registerDependentBean(dep, beanName);
				try {
							getBean(dep);
						}
						catch (NoSuchBeanDefinitionException ex) {
							throw new BeanCreationException(mbd.getResourceDescription(), beanName,
									"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
						}
					}
				}

判断是否为单例,如果是单例并去实例化bean

if (mbd.isSingleton()) {
	sharedInstance = getSingleton(beanName, () -> {
		try {
			return createBean(beanName, mbd, args);
		}
catch (BeansException ex) {
							// Explicitly remove instance from singleton cache: It might have been put there
							// eagerly by the creation process, to allow for circular reference resolution.
							// Also remove any beans that received a temporary reference to the bean.
							destroySingleton(beanName);
							throw ex;
						}
					});
	bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
	}

先了解什么是BeanPostProcessor,BeanPostProcessor是Spring容器的一个扩展点,可以进行自定义的实例化、初始化、依赖装配、依赖 检查等流程,即可以覆盖默认的实例化,也可以增强初始化、依赖注入、依赖检查等流程。

public interface BeanPostProcessor {
    @Nullable    
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {        
return bean;    
}
 @Nullable    
default Object postProcessAfterInitialization(Object bean, String beanName) throws  BeansException {        
return bean;    
} 
}

 

在创建bean的时候会经过9个BeanPostProcessor的调用,现在重点看createBean方法,

1、第一次调用后置处理器

Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
// 直接返回替代的对象实例,不再实例化目标对象
return bean;
}

实例化前的后置处理器调用 InstantiationAwareBeanPostProcessor,通过如上代码可以进行实例化的预处理(自定义实例化bean,如创建相应的代理对象)和后处理(如 进行自定义实例化的bean的依赖装配)。一般该bean如果是被AOP增强过的话,就会返回一个代理bean对象。调用InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation方法

2、第二次调用后置处理器

是在doCreateBean中调用,执行该方法后bean的实例也就创建出来了。

instanceWrapper = createBeanInstance(beanName, mbd, args);

确定要为给定bean使用的候选构造器,检查所有已注册的构造器,实现类 AutowiredAnnotationBeanPostProcessor,扫描@Autowired修饰的构造器,判断创建对象所用的构造 器(deafult,primary)。调用SmartInstantiationAwareBeanPostProcessor的determineCandidateConstructors方法


3、第三次调用后置处理器

applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);

允许后置处理器修改合并的bean定义 ,实现类AutowiredAnnotationBeanPostProcessor,用于扫描 @Autowired和@Value修饰的属性和方法,封装到InjectionMetadata。调用MergedBeanDefinitionPostProcessor的postProcessMergedBeanDefinition。

4、第四次调用后置处理器

addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));

获得提前暴露的bean引用。主要用于解决循环引用的问题,只有单例对象才会调用此方法。调用SmartInstantiationAwareBeanPostProcessor的getEarlyBeanReference方法

5、第五次,六次调用后置处理器

populateBean(beanName, mbd, instanceWrapper)

第五次:

if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
			for (BeanPostProcessor bp : getBeanPostProcessors()) {
				if (bp instanceof InstantiationAwareBeanPostProcessor) {
					InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
					if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
						continueWithPropertyPopulation = false;
						break;
					}
				}
			}
		}

调用InstantiationAwareBeanPostProcessor的postProcessAfterInstantiation方法

在目标对象实例化之后调用,此时对象被实例化,但是对象的属性还未设置。如果该方法返回fasle,则 会忽略之后的属性设置。返回true,按正常流程设置属性值 。

第六次:

	for (BeanPostProcessor bp : getBeanPostProcessors()) {
				if (bp instanceof InstantiationAwareBeanPostProcessor) {

					InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
					PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
					if (pvsToUse == null) {
						if (filteredPds == null) {
							filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
						}
						pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
						if (pvsToUse == null) {
							return;
						}
					}
					pvs = pvsToUse;
				}
			}

可以在该方法内对属性值进行修改(此时属性值还未设置,但可以修改原本会设置的进去的属性值),如果postProcessAfterInstantiation方法返回false,该方法不会调用。使用了@Autowired 属性注入是调用AutowiredAnnotationBeanPostProcessor

6、第七,八次调用后置处理器

exposedObject = initializeBean(beanName, exposedObject, mbd)

三种初始化方法

在@Bean注解中执行,在实例方法上添加注解@PostConstruct,实现InitializingBean接口。

第七次:

wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName)

在方法内还会执行bean生命周期回调的init方法,还会实现InitializingBean接口的调用,因为RequestMappingHandlerMapping的父类实现了InitializingBean接口,所以这里会完成RequestMapping的注册。

如果配置了@PostConstruct 会调用InitDestroyAnnotationBeanPostProcessor

((InitializingBean) bean).afterPropertiesSet();

第八次:

wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);

这里主要是aop的实现,AbstractAutoProxyCreator调用postProcessAfterInitialization

7、第九次调用后置处理器

registerDisposableBeanIfNecessary(beanName, bean, mbd)

确定给定的bean实例是否需要销毁后处理器,DestructionAwareBeanPostProcessor bean的销毁后置处理器

 

12、finishRefresh()

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

initLifecycleProcessor()方法初始化和生命周期有关的bean后处理器,我们可以写一个LifecycleProcessor接口的实现类,容器刷新完毕,就会调回调该接口的onrefresh()方法,如果是容器关闭,那就会调用该接口的onclose()方法。

getLifecycleProcessor().onRefresh()拿到前面定义的生命周期处理器,回调onRefresh()方法

publishEvent()该方法发布容器刷新完成事件

 

总结:

实现BeanFactoryPostProcessor接口,初始化BeanFactory时候会调用。
实现InitializingBean接口,bean在初始化的时候调用afterPropertiesSet();
实现BeanPostProcessor,可以在每个bean前后调用一次。
使用init-method初始化的方法执行。
实现FactoryBean工厂接口自定义的bean初始化。
实现DisposableBean接口,销毁bean时调用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值