Spring之Bean的生命周期详解
在Spring框架中,Bean的创建和管理是通过Spring容器来完成的。Spring Bean生命周期包括实例化、属性填充、初始化、销毁等多个步骤。本文将详细解析Spring中Bean的生命周期,并重点介绍AbstractAutowireCapableBeanFactory
类中的createBean
方法及其相关的方法调用。
Bean的生命周期概述
Spring Bean的生命周期分为多个阶段,每个阶段都由特定的方法和机制来完成:
- 实例化前准备:解析Bean定义,确定Bean类型。
- 实例化:创建Bean实例。
- 属性填充:对Bean的各个属性进行依赖注入。
- 初始化:执行自定义的初始化方法和Spring的
BeanPostProcessor
回调。 - 使用:Bean已经完全初始化并可以使用。
- 销毁:容器关闭时,对Bean进行清理工作,执行销毁方法。
下面我们将通过源码详细解析每个步骤的实现。
createBean
方法详解
createBean
方法是Spring中创建Bean实例的核心方法。该方法的实现位于AbstractAutowireCapableBeanFactory
类中:
@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类已解析并克隆bean定义以防止共享的bean定义中的动态解析类无法存储Class<?> resolvedClass = resolveBeanClass(mbd, beanName);if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {mbdToUse = new RootBeanDefinition(mbd);mbdToUse.setBeanClass(resolvedClass);}// 准备方法重写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 {Object beanInstance = doCreateBean(beanName, mbdToUse, args);if (logger.isTraceEnabled()) {logger.trace("Finished creating instance of bean '" + beanName + "'");}return beanInstance;} catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {throw ex;} catch (Throwable ex) {throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);}
}
1. resolveBeanClass
方法
在Bean实例化之前,首先需要解析Bean的类:
protected Class<?> resolveBeanClass(RootBeanDefinition mbd, String beanName, Class<?>... typesToMatch)throws CannotLoadBeanClassException {try {if (mbd.hasBeanClass()) {return mbd.getBeanClass();}if (System.getSecurityManager() != null) {return AccessController.doPrivileged((PrivilegedExceptionAction<Class<?>>) () -> doResolveBeanClass(mbd, typesToMatch), getAccessControlContext());} else {return doResolveBeanClass(mbd, typesToMatch);}} catch (PrivilegedActionException pae) {ClassNotFoundException ex = (ClassNotFoundException) pae.getException();throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex);} catch (ClassNotFoundException ex) {throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex);} catch (LinkageError err) {throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), err);}
}
2. prepareMethodOverrides
方法
检查和准备Bean定义中定义的方法重写:
public void prepareMethodOverrides() throws BeanDefinitionValidationException {if (hasMethodOverrides()) {getMethodOverrides().getOverrides().forEach(this::prepareMethodOverride);}
}
3. resolveBeforeInstantiation
方法
在实例化Bean之前,调用BeanPostProcessor
来尝试返回代理对象:
@Nullable
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {Object bean = null;if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {Class<?> targetType = determineTargetType(beanName, mbd);if (targetType != null) {bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);if (bean != null) {bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);}}}mbd.beforeInstantiationResolved = (bean != null);}return bean;
}
3.1 applyBeanPostProcessorsBeforeInstantiation
方法
调用InstantiationAwareBeanPostProcessor
的postProcessBeforeInstantiation
方法:
@Nullable
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {Object result = bp.postProcessBeforeInstantiation(beanClass, beanName);if (result != null) {return result;}}return null;
}
3.2 applyBeanPostProcessorsAfterInitialization
方法
调用BeanPostProcessor
的postProcessAfterInitialization
方法:
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)throws BeansException {Object result = existingBean;for (BeanPostProcessor processor : getBeanPostProcessors()) {Object current = processor.postProcessAfterInitialization(result, beanName);if (current == null) {return result;}result = current;}return result;
}
4. doCreateBean
方法
实际创建Bean实例的主要方法:
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)throws BeanCreationException {BeanWrapper instanceWrapper = null;if (mbd.isSingleton()) {instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);}if (instanceWrapper == null) {instanceWrapper = createBeanInstance(beanName, mbd, args);}Object bean = instanceWrapper.getWrappedInstance();Class<?> beanType = instanceWrapper.getWrappedClass();if (beanType != NullBean.class) {mbd.resolvedTargetType = beanType;}synchronized (mbd.postProcessingLock) {if (!mbd.postProcessed) {try {applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);} catch (Throwable ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Post-processing of merged bean definition failed", ex);}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");}addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));}Object exposedObject = bean;try {populateBean(beanName, mbd, instanceWrapper);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) {Object earlySingletonReference = getSingleton(beanName, false);if (earlySingletonReference != null) {if (exposedObject == bean) {exposedObject = earlySingletonReference;} else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {String[] dependentBeans = getDependentBeans(beanName);Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);for (String dependentBean : dependentBeans) {if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {actualDependentBeans.add(dependentBean);}}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 {registerDisposableBeanIfNecessary(beanName, bean, mbd);} catch (BeanDefinitionValidationException ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);}return exposedObject;
}
4.1 createBeanInstance
方法
创建Bean实例的方法:
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {// 构造方法自动装配Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR || mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {return autowireConstructor(beanName, mbd, ctors, args);}// 使用工厂方法创建beanif (mbd.getFactoryMethodName() != null) {return instantiateUsingFactoryMethod(beanName, mbd, args);}// 默认的无参构造函数实例化return instantiateBean(beanName, mbd);
}
4.2 populateBean
方法
对Bean的属性进行填充:
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {PropertyValues pvs = mbd.getPropertyValues();if (bw == null) {if (!pvs.isEmpty()) {throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");} else {return;}}if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME || mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {MutablePropertyValues newPvs = new MutablePropertyValues(pvs);// Add property values based on autowire by name if applicable.if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME) {autowireByName(beanName, mbd, bw, newPvs);}// Add property values based on autowire by type if applicable.if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {autowireByType(beanName, mbd, bw, newPvs);}pvs = newPvs;}applyPropertyValues(beanName, mbd, bw, pvs);
}
4.3 initializeBean
方法
对Bean进行初始化,包括调用BeanPostProcessor
:
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {invokeAwareMethods(beanName, bean);Object wrappedBean = bean;if (mbd == null || !mbd.isSynthetic()) {wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);}try {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()) {wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);}return wrappedBean;
}
5. registerDisposableBeanIfNecessary
方法
注册需要销毁的Bean:
protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null);if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {if (mbd.isSingleton()) {registerDisposableBean(beanName, new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessorCache().destruction, acc));} else {Scope scope = this.scopes.get(mbd.getScope());if (scope == null) {throw new IllegalStateException("No Scope registered for scope name '" + mbd.getScope() + "'");}scope.registerDestructionCallback(beanName, new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessorCache().destruction, acc));}}
}
详细分析每个步骤
为了更全面地理解Spring Bean的生命周期,我们将详细解析每个步骤,探讨其内部机制和关键方法。
实例化前准备
实例化前的准备工作包括解析Bean的类信息和准备方法重写。这一步骤确保在实例化Bean之前,所有必要的元数据和配置已经到位。
解析Bean的类
解析Bean的类是通过resolveBeanClass
方法实现的。该方法负责将Bean定义中的类名解析为实际的Class对象:
protected Class<?> resolveBeanClass(RootBeanDefinition mbd, String beanName, Class<?>... typesToMatch)throws CannotLoadBeanClassException {try {if (mbd.hasBeanClass()) {return mbd.getBeanClass();}if (System.getSecurityManager() != null) {return AccessController.doPrivileged((PrivilegedExceptionAction<Class<?>>) () -> doResolveBeanClass(mbd, typesToMatch), getAccessControlContext());} else {return doResolveBeanClass(mbd, typesToMatch);}} catch (PrivilegedActionException pae) {ClassNotFoundException ex = (ClassNotFoundException) pae.getException();throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex);} catch (ClassNotFoundException ex) {throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex);} catch (LinkageError err) {throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), err);}
}
在解析过程中,Spring会检查Bean定义中是否已经包含了Class对象。如果没有,Spring会根据Bean的类名进行加载。这个过程可以在受控的安全环境中进行,以确保在安全管理器启用的情况下也能够正确加载类。
准备方法重写
准备方法重写是通过prepareMethodOverrides
方法实现的。该方法会检查Bean定义中是否包含了需要重写的方法,并进行相应的准备工作:
public void prepareMethodOverrides() throws BeanDefinitionValidationException {if (hasMethodOverrides()) {getMethodOverrides().getOverrides().forEach(this::prepareMethodOverride);}
}
方法重写的准备工作包括验证方法签名和确保方法的可访问性。这一步骤对于支持方法重写功能的Bean非常重要,例如使用CGLIB动态代理的Bean。
实例化Bean
实例化Bean是通过调用createBeanInstance
方法来实现的。该方法负责根据不同的情况创建Bean实例,包括构造方法自动装配、工厂方法实例化以及默认的无参构造函数实例化。
构造方法自动装配
如果Bean定义中包含构造函数参数,或者需要进行构造函数自动装配,Spring会调用autowireConstructor
方法:
protected BeanWrapper autowireConstructor(String beanName, RootBeanDefinition mbd, Constructor<?>[] chosenCtors, Object[] explicitArgs) {return new ConstructorResolver(this).autowireConstructor(beanName, mbd, chosenCtors, explicitArgs);
}
autowireConstructor
方法会根据Bean定义中的构造函数参数信息选择合适的构造函数,并通过反射机制创建Bean实例。
工厂方法实例化
如果Bean定义中指定了工厂方法,Spring会调用instantiateUsingFactoryMethod
方法:
protected BeanWrapper instantiateUsingFactoryMethod(String beanName, RootBeanDefinition mbd, @Nullable Object[] explicitArgs) {return new ConstructorResolver(this).instantiateUsingFactoryMethod(beanName, mbd, explicitArgs);
}
工厂方法实例化会根据Bean定义中的工厂方法名,通过反射调用工厂方法创建Bean实例。
默认无参构造函数实例化
如果Bean定义中既没有构造函数参数,也没有工厂方法,Spring会调用instantiateBean
方法:
protected BeanWrapper instantiateBean(String beanName, RootBeanDefinition mbd) {try {Object beanInstance;if (System.getSecurityManager() != null) {beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->getInstantiationStrategy().instantiate(mbd, beanName, this), getAccessControlContext());} else {beanInstance =getInstantiationStrategy().instantiate(mbd, beanName, this);}BeanWrapper bw = new BeanWrapperImpl(beanInstance);initBeanWrapper(bw);return bw;} catch (Throwable ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);}
}
该方法会调用默认的无参构造函数创建Bean实例,并返回一个包装了Bean实例的BeanWrapper
对象。
属性填充
属性填充是通过populateBean
方法来实现的。该方法负责对Bean实例的属性进行依赖注入,包括自动装配和手动指定的属性值。
自动装配
自动装配是通过autowireByName
和autowireByType
方法来实现的。这些方法会根据Bean定义中的自动装配模式,按照名称或类型进行依赖注入。
手动指定的属性值
如果Bean定义中包含了手动指定的属性值,Spring会调用applyPropertyValues
方法将这些属性值设置到Bean实例上:
protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {if (pvs.isEmpty()) {return;}MutablePropertyValues mpvs = (pvs instanceof MutablePropertyValues ? (MutablePropertyValues) pvs : new MutablePropertyValues(pvs));List<PropertyValue> original = mpvs.getPropertyValueList();TypeConverter converter = getCustomTypeConverter();if (converter == null) {converter = bw;}BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);// Create a deep copy, resolving any references for values.for (PropertyValue pv : original) {if (pv.isConverted()) {continue;}Object originalValue = pv.getValue();Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);PropertyValue newPv = new PropertyValue(pv.getName(), resolvedValue);newPv.setConverted();mpvs.addPropertyValue(newPv);}bw.setPropertyValues(mpvs);
}
该方法会解析属性值中的依赖项,并将解析后的值设置到Bean实例上。
初始化Bean
初始化Bean是通过initializeBean
方法来实现的。该方法会调用一系列的回调方法,包括BeanPostProcessor
的postProcessBeforeInitialization
和postProcessAfterInitialization
方法,以及Bean实例中的初始化方法。
调用BeanPostProcessor
回调
BeanPostProcessor
回调方法用于在Bean初始化的前后执行一些自定义逻辑,例如代理对象的创建和自定义初始化逻辑的执行。
调用Bean实例的初始化方法
如果Bean实例实现了InitializingBean
接口,Spring会调用afterPropertiesSet
方法。如果Bean定义中指定了初始化方法,Spring会通过反射调用该方法:
protected void invokeInitMethods(String beanName, Object bean, RootBeanDefinition mbd) throws Throwable {boolean isInitializingBean = (bean instanceof InitializingBean);if (isInitializingBean) {if (System.getSecurityManager() != null) {try {AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {((InitializingBean) bean).afterPropertiesSet();return null;}, getAccessControlContext());} catch (PrivilegedActionException pae) {throw pae.getException();}} else {((InitializingBean) bean).afterPropertiesSet();}}if (mbd != null && bean.getClass() != NullBean.class) {String initMethodName = mbd.getInitMethodName();if (StringUtils.hasLength(initMethodName) && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName))) {invokeCustomInitMethod(beanName, bean, mbd);}}
}
销毁Bean
销毁Bean是通过注册销毁回调方法来实现的。当Spring容器关闭时,会调用这些销毁回调方法对Bean进行清理工作。
注册销毁回调
注册销毁回调是通过registerDisposableBeanIfNecessary
方法来实现的。该方法会根据Bean的作用域和生命周期,注册相应的销毁回调:
protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null);if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {if (mbd.isSingleton()) {registerDisposableBean(beanName, new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessorCache().destruction, acc));} else {Scope scope = this.scopes.get(mbd.getScope());if (scope == null) {throw new IllegalStateException("No Scope registered for scope name '" + mbd.getScope() + "'");}scope.registerDestructionCallback(beanName, new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessorCache().destruction, acc));}}
}
总结
Spring框架通过一系列复杂的步骤和机制,管理Bean的整个生命周期。理解这些机制有助于开发人员更好地利用Spring框架,编写高效、可维护的代码。通过深入研究AbstractAutowireCapableBeanFactory
类中的createBean
方法及其相关的内部调用,我们可以清晰地看到Spring是如何创建、初始化和销毁Bean的。
这些机制不仅提供了强大的灵活性和可扩展性,还通过各种回调和扩展点,允许开发人员在Bean的生命周期各个阶段插入自定义逻辑,从而满足各种复杂的应用需求。
了解Spring Bean生命周期的内部工作原理,对于解决实际开发中遇到的问题和优化应用性能具有重要意义。希望本文的详细解析能够帮助您更深入地理解Spring框架,提升您的开发技能。