在面向对象编程中,对象是程序的基本单元,而bean则是Spring框架中最基本的单元.Spring框架的核心是IoC容器和AOP框架,其中IoC容器负责创建,管理和维护对象,AOP框架负责提供横切关注点的解决方案.在Spring IoC容器中,bean是被创建,管理和维护的对象.在本文中,我们将重点探讨六个关键函数,即:
它们是Spring框架中创建和管理bean的核心函数.本文将逐一介绍这六个函数的作用,工作流程以及源码解析,以帮助开发者深入理解Spring框架的IoC容器.
注意:本文使用的Spring版本为:5.3.12
/**
* 预先实例化单例bean,即在BeanFactory初始化时将所有标记为singleton的bean都实例化
*
* @throws BeansException
*/
public void preInstantiateSingletons() throws BeansException {
if (logger.isTraceEnabled()) {
logger.trace("Pre-instantiating singletons in " + this);
}
// 获取所有的BeanDefinition的名称列表
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
for (String beanName : beanNames) {
// 获取Bean定义信息
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 FactoryBean) {
FactoryBean<?> factory = (FactoryBean<?>) bean;
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());
}
if (isEagerInit) {
// 需要提前实例化则调用getBean
getBean(beanName);
}
}
}
else {
// 不是FactoryBean类型直接调用getBean
getBean(beanName);
}
}
}
for (String beanName : beanNames) {
// 获取Bean实例
Object singletonInstance = getSingleton(beanName);
// 判断是否实现SmartInitializingSingleton接口
if (singletonInstance instanceof SmartInitializingSingleton) {
// 应用启动计时
StartupStep smartInitialize = this.getApplicationStartup().start("spring.beans.smart-initialize")
.tag("beanName", beanName);
SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
// 安全权限校验
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
// 执行SmartInitializingSingleton的afterSingletonsInstantiated
smartSingleton.afterSingletonsInstantiated();
return null;
}, getAccessControlContext());
}
else {
smartSingleton.afterSingletonsInstantiated();
}
// 应用启动计时结束
smartInitialize.end();
}
}
}
该方法的主要工作流程如下:
/**
* 该方法用于获取一个bean实例,
* 如果改bean实例还步存在,会先执行创建bean的流程,包含实例化,属性注入,初始化等.
*
* @param name 要获取的Bean名称
* @param requiredType Bean的类型,如果指定,BeanFactory会根据此类型返回相应的Bean实例
* @param args 创建Bean实例使用的参数,可以为null,表示无参构造
* @param typeCheckOnly 如果为true,则只检查
* @param
* @return
* @throws BeansException
*/
protected <T> T doGetBean(
String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
throws BeansException {
// 获取转换后的bean名称
String beanName = transformedBeanName(name);
Object beanInstance;
// 尝试获取单例bean
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
// 如果存在单例bean并且没有构造函数参数,直接返回
if (logger.isTraceEnabled()) {
if (isSingletonCurrentlyInCreation(beanName)) {
logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference");
}
else {
logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
}
}
// 获取单例bean实例
beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
// 如果不存在单例bean或者存在构造函数参数则需要创建bean实例
if (isPrototypeCurrentlyInCreation(beanName)) {
// 如果是原型bean,则抛异常
throw new BeanCurrentlyInCreationException(beanName);
}
// 获取父BeanFactory
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// 如果存在父BeanFactory并且当前BeanFactory不存在bean定义,则尝试从父BeanFactory中获取bean
String nameToLookup = originalBeanName(name);
if (parentBeanFactory instanceof AbstractBeanFactory) {
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
nameToLookup, requiredType, args, typeCheckOnly);
}
else if (args != null) {
// 代理到具有构造函数参数的父工厂
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else if (requiredType != null) {
// No args -> delegate to standard getBean method.
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
else {
return (T) parentBeanFactory.getBean(nameToLookup);
}
}
if (!typeCheckOnly) {
// 如果不仅仅是检查bean是否存在,标记bean正在创建中,防止循环依赖
markBeanAsCreated(beanName);
}
// 开始创建bean的计时器
StartupStep beanCreation = this.applicationStartup.start("spring.beans.instantiate")
.tag("beanName", name);
try {
if (requiredType != null) {
beanCreation.tag("beanType", requiredType::toString);
}
// 获取合并后的bean定义
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
// 检查合并后的bean定义
checkMergedBeanDefinition(mbd, beanName, args);
// 获取dependsOn属性,表示当前beanName所依赖的,当前bean创建之前dependsOn所依赖的bean必须已经创建好了
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
// beanName是不是被dep依赖了,如果是则出现了循环依赖
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
// dep被beanName给依赖了,更新dependentBeanMap
registerDependentBean(dep, beanName);
try {
// 创建所依赖的Bean
getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
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;
}
});
beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
else if (mbd.isPrototype()) {
// 如果该bean是原型bean且不是循环依赖,则创建新的bean实例返回
Object prototypeInstance = null;
try {
// 原型bean创建前的处理
beforePrototypeCreation(beanName);
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
// 原型bean创建后的处理
afterPrototypeCreation(beanName);
}
// 获取bean实例并返回
beanInstance = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
else {
// 如果bean的作用域是自定义作用域,则使用相应的Scope对象获取bean实例并返回
String scopeName = mbd.getScope();
if (!StringUtils.hasLength(scopeName)) {
throw new IllegalStateException("No scope name defined for bean '" + beanName + "'");
}
Scope scope = this.scopes.get(scopeName);
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
}
try {
// 获取bean实例并返回
Object scopedInstance = scope.get(beanName, () -> {
// bean创建前的处理
beforePrototypeCreation(beanName);
try {
return createBean(beanName, mbd, args);
}
finally {
// bean创建后的处理
afterPrototypeCreation(beanName);
}
});
beanInstance = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
catch (IllegalStateException ex) {
throw new ScopeNotActiveException(beanName, scopeName, ex);
}
}
}
catch (BeansException ex) {
beanCreation.tag("exception", ex.getClass().toString());
beanCreation.tag("message", String.valueOf(ex.getMessage()));
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
finally {
beanCreation.end();
}
}
// 检查通过name所获得到的beanInstance的类型是否是requiredType
return adaptBeanInstance(name, beanInstance, requiredType);
}
该方法的主要工作流程如下:
/**
* 根据给定的beanName和RootBeanDefinition创建一个新的bean实例,
* 并应用所有bean属性的后处理器(如自动装配,Aware接口,BeanPostProcessors等)
*
* @param beanName 要创建的bean名称
* @param mbd RootBeanDefinition对象,包含bean的属性和配置信息
* @param args 传递给bean的构造函数参数,可以为null(无参构造)
* @return
* @throws BeanCreationException
*/
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
if (logger.isTraceEnabled()) {
logger.trace("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;
// 解析bean的Class,并克隆bean定义
// 防止动态生成的Class不能被储存再共享的合并bean定义中
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// 准备方法重写
// 如果校验失败则抛出BeanDefinitionValidationException异常
try {
mbdToUse.prepareMethodOverrides();
} catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
// 允许BeanPostProcessors再实例化bean之前返回代理对象
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
} catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
try {
// 创建bean实例,如果创建失败则抛出异常
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isTraceEnabled()) {
logger.trace("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
} catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
// 如果之前检测到异常,则直接抛出已检测到的异常
// 或者单例状态异常,需要通知DefaultSingletonBeanRegistry处理
throw ex;
} catch (Throwable ex) {
// 否则抛出BeanCreationException异常
throw new BeanCreationException(
mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
}
}
该方法主要工作流程如下:
/**
* 实际创建指定bean
*
* @param beanName 要创建的bean名称
* @param mbd RootBeanDefinition对象,包含bean的属性和配置信息
* @param args 传递给bean的构造函数参数,可以为null(无参构造)
* @return
* @throws BeanCreationException
*/
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
// 创建BeanWrapper对象,用于封装创建出来的bean实例
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
// 如果是单例模式,则从单例缓存中获取该BeanWrapper实例
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
// 如果单例缓存中没有该bean的BeanWrapper对象的实例,则创建该bean的BeanWrapper对象
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
// 获取封装再BeanWrapper中的bean实例和类类型
Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
// 如果bean类型不是NullBean,则将该bean的类型设置到mbd的resolvedTargetType中
mbd.resolvedTargetType = beanType;
}
// 同步锁,用于避免多个线程同时执行后处理器的postProcessBeforeInitialization方法
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
// 如果还没有进行后处理
try {
// 应用bean定义合并后的后处理器
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
} catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
// 设置mbd的postProcessed属性未true
mbd.postProcessed = true;
}
}
// 是否提前暴露单例
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
// 如果是提前暴露单例
if (logger.isTraceEnabled()) {
logger.trace("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
// 添加一个早期的Bean引用对象到singletonFactories中,便于后续或许到该Bean实例
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// 暴露的对象
Object exposedObject = bean;
try {
// 填充bean属性
populateBean(beanName, mbd, instanceWrapper);
// 初始化bean
exposedObject = initializeBean(beanName, exposedObject, mbd);
} catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
} else {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
}
if (earlySingletonExposure) {
// 如果存在循环依赖,则需要提前暴露当前bean对象的引用
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
// 如果早期引用存在,更新exposeObject
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
} else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
// 否则,如果存在于依赖当前bean的bean
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
// 如果依赖的bean已经被创建,而且不是为了类型检查而创建的,则将其添加到actualDependentBeans中
actualDependentBeans.add(dependentBean);
}
}
// 如果actualDependentBeans不为空,说明存在未被包装的依赖bean
if (!actualDependentBeans.isEmpty()) {
throw new BeanCurrentlyInCreationException(beanName,
"Bean with name '" + beanName + "' has been injected into other beans [" +
StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
"] in its raw version as part of a circular reference, but has eventually been " +
"wrapped. This means that said other beans do not use the final version of the " +
"bean. This is often the result of over-eager type matching - consider using " +
"'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
try {
// 注册当前bean的销毁回调函数,用于再容器关闭时进行资源释放
registerDisposableBeanIfNecessary(beanName, bean, mbd);
} catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
该方法主要工作流程如下:
需要注意的是,再初始化bean之前,要先进行bean属性填充.再属性填充过程中,可能会出现依赖注入的情况,即需要创建其他的bean实例.如果创建bean实例也依赖于当前正在创建的bean实例,就会出现循环依赖的情况.为了解决这个问题,该方法使用了提前暴露单例的技术,将正在创建的bean实例提前暴露出去,便于后续创建其他的bean实例时使用.
/**
* 初始化给定的bean实例,应用工厂回调,初始化方法和bean后置处理器
*
* @param beanName 要初始化的bean名称
* @param bean 要初始化的bean实例
* @param mbd 要使用的bean定义
* @return
*/
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
// 如果存在SecurityManager,使用特权方式调用invokeAwareMethods
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
// 调用BeanNameAware,BeanClassLoaderAware和BeanFactoryAware接口的相关方法
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
} else {
// 调用BeanNameAware,BeanClassLoaderAware和BeanFactoryAware接口的相关方法
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
// 调用BeanPostProcessor的postProcessBeforeInitialization方法
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
// 调用bean的初始化方法
invokeInitMethods(beanName, wrappedBean, mbd);
} catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
// 调用BeanPostProcessor的postProcessAfterInitialization方法
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
该方法工作流程如下:
需要注意的是,如果再调用bean的初始化方法时出现异常,则抛出一个BeanCreationException异常.同时该方法还包含了对安全管理器的处理,如果存在安全管理器,则使用特权方式来调用invokeAwareMethods方法
/**
* 销毁所有已经注册的单例bean
*/
public void destroySingletons() {
if (logger.isTraceEnabled()) {
logger.trace("Destroying singletons in " + this);
}
// 同步锁定singletonObjects,将singletonsCurrentlyInDestruction设置为true
synchronized (this.singletonObjects) {
this.singletonsCurrentlyInDestruction = true;
}
// 获取所有需要销毁的bean名称
String[] disposableBeanNames;
synchronized (this.disposableBeans) {
disposableBeanNames = StringUtils.toStringArray(this.disposableBeans.keySet());
}
for (int i = disposableBeanNames.length - 1; i >= 0; i--) {
// 逆序遍历所有需要销毁的bean,并调用destroySingleton方法进行销毁
destroySingleton(disposableBeanNames[i]);
}
// 清空containedBeanMap,dependentBeanMap和dependenciesForBeanMap
this.containedBeanMap.clear();
this.dependentBeanMap.clear();
this.dependenciesForBeanMap.clear();
// 清空所有缓存的单例实例
clearSingletonCache();
}
该方法工作流程如下:
需要注意的时,该方法时再单例bean的销毁期间调用的,因此需要保持所有单例实例的同步,并且需要检查并清除相关的依赖项,以确保正确的销毁顺序.