继上一篇文章 Spring如何加载IOC容器以及装载Bean源码解读,从源码中我们分析了Spring容器的加载过程,Bean的创建。在本篇文章,我们继续分析Bean的创建过程源码以及Bean的生命周期。根据源码总结出Bean的生命周期流程图如下:
我们继续追踪源码
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
RootBeanDefinition mbdToUse = mbd;
// 1、确保此时bean类已经被解析,并且在动态解析类不能存储在共享合并bean定义中时克隆bean定义。
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// 2、准备和验证配置的方法注入
// 注意:这里处理的是replace-method和lookup-method方法注入,而不是@Override注解
try {
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),beanName, "Validation of method overrides failed", ex);
}
try {
// 3、让beanPostprocessor有机会返回一个代理而不是目标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 {
// 4、执行bean创建,并返回bean的实例
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
return beanInstance;
}
catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
}
}
其中,又发现了第4步,4、执行bean创建,并返回bean的实例doCreateBean(beanName, mbdToUse, args);位于类AbstractAutowireCapableBeanFactory中,该步骤是创建Bean实际方法,其中,我们也能发现Spring中实际做事的都是doXX的方法,我们继续跟踪doCreateBean方法如下:
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) throws BeanCreationException {
// ① 实例化bean
BeanWrapper instanceWrapper = null;
// 注意factoryBeanInstanceCache是ConcurrentMap,remove方法会返回删除的键值(如果不存在返回null)
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
// 如果factoryBeanInstanceCache没有缓存对应的BeanWrapper,则重新创建bean实例
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
// ② 允许MergedBeanDefinitionPostProcessor后处理器修改已合并的bean定义。
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;
}
}
// ③ 提前缓存ObjectFactory以解决bean之间的循环依赖
// mbd.isSingleton()->是否单例
// allowCircularReferences->是否允许循环依赖
// isSingletonCurrentlyInCreation->该bean是否创建中
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// ④ 初始化bean实例 这里大家要与第①步区分开,到这里bean已经完成了实例化,但是还没有完成初始化的操作,例如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) {
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 " +
"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
// Register bean as disposable.
try {
// ⑥ 根据bean的作用域注册bean
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
// ⑦ 返回bean实例
return exposedObject;
}
以上为创建Bean步骤,我们分析其中重要的步骤
第1步,实例化方法为:createBeanInstance(beanName, mbd, args),跟踪代码会发现实例化主要有三种方式,1??工厂方法(实例工厂和静态工厂);2??构造函数实例化(无参构造和有参构造);3??通过实例提供者实例化(Spring5新增的实例化策略)
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// 确保此时beanClass已经被解析
Class<?> beanClass = resolveBeanClass(mbd, beanName);
// beanClass不为空,且beanClass的修饰符为不为public,且不允许访问非公共构造函数和方法,则抛出异常
if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
}
// ① Spring5.0新增的实例化策略,如果设置了该策略,将会覆盖构造方法和工厂方法实例化策略
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return obtainFromSupplier(instanceSupplier, beanName);
}
// ② 如果有工厂方法的话,则使用工厂方法实例化bean
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
// ③ 当创建一个相同的bean时,使用之间保存的快照
// 这里可能会有一个疑问,什么时候会创建相同的bean呢?
// ③-->① 单例模式: Spring不会缓存该模式的实例,那么对于单例模式的bean,什么时候会用到该实例化策略呢?
// 我们知道对于IoC容器除了可以索取bean之外,还能销毁bean,当我们调用xmlBeanFactory.destroyBean(myBeanName,myBeanInstance),
// 销毁bean时,容器是不会销毁已经解析的构造函数快照的,如果再次调用xmlBeanFactory.getBean(myBeanName)时,就会使用该策略了.
// ③-->② 原型模式: 对于该模式的理解就简单了,IoC容器不会缓存原型模式bean的实例,当我们第二次向容器索取同一个bean时,就会使用该策略了.
boolean resolved = false;
boolean autowireNecessary = false;
if (args == null) {
synchronized (mbd.constructorArgumentLock) {
if (mbd.resolvedConstructorOrFactoryMethod != null) {
resolved = true;
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
// 如果该bean已经被解析过
if (resolved) {
// 使用已经解析过的构造函数实例化
if (autowireNecessary) {
return autowireConstructor(beanName, mbd, null, null);
}
// 使用默认无参构造函数实例化
else {
return instantiateBean(beanName, mbd);
}
}
// ④ 确定需要使用的构造函数
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
return autowireConstructor(beanName, mbd, ctors, args);
}
// ⑤ 无任何的特殊处理,则使用默认的无参构造函数实例化bean
return instantiateBean(beanName, mbd);
}
第4步中, populateBean(beanName, mbd, instanceWrapper);属性填充方法,根据装配类型注入,主要有byName注入和byType注入
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
// ① 前置判断
// 如果BeanWrapper对象为null,则说明没有bean的实例
if (bw == null) {
// RootBeanDefinition中有属性,但是bean的实例为空,抛出异常
if (mbd.hasPropertyValues()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
}
else {
// RootBeanDefinition中没有属性,直接返回
return;
}
}
// ② 应用InstantiationAwareBeanPostProcessor处理器
// 在设置属性之前,给InstantiationAwareBeanPostProcessor一个修改bean状态的机会
boolean continueWithPropertyPopulation = true;
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
// 是否继续填充bean属性
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
continueWithPropertyPopulation = false;
break;
}
}
}
}
// ③ 如果InstantiationAwareBeanPostProcessor停止了对bean属性的填充,则直接返回
if (!continueWithPropertyPopulation) {
return;
}
// 获取PropertyValues属性
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
// ④ 解析自动装配类型
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME || mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// byName注入
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// byType注入
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
// ⑤ 判断是否有InstantiationAwareBeanPostProcessors处理器,并进行处理
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);
PropertyDescriptor[] filteredPds = null;
if (hasInstAwareBpps) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
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;
}
}
}
// ⑥ 依赖检查
if (needsDepCheck) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
checkDependencies(beanName, mbd, filteredPds, pvs);
}
// ⑦ 应用属性
if (pvs != null) {
applyPropertyValues(beanName, mbd, bw, pvs);
}
}
接下来继续看第4步中初始化bean方法,exposedObject = initializeBean(beanName, exposedObject, mbd);完成有关bean的生命周期的调用AwareMethods、应用bean前置处理器、调用bean的init_method初始化方法、应用bean后置处理器,该方法相当重要啊~
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
// 1、调用各种AwareMethods
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
invokeAwareMethods(beanName, bean);
}
// 2、应用bean前置处理器
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
// 3、调用bean的init_method初始化方法
try {
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException((mbd != null ? mbd.getResourceDescription() : null),beanName,"Invocation of init method failed", ex);
}
// 4、应用bean后置处理器
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
至此,Spring容器中自定义单例Bean创建完成并返回。其实,在创建的过程中,还有很多重点问题,比如:如何根据FactoryBean创建Bean,如何根据构造函数创建Bean,特别是Spring是如何解决Bean循环依赖的问题等等,在以后的文章我们会继续分享。
不断分享开发过程用到的技术和面试经常被问到的问题,如果您也对IT技术比较感兴趣可以「关注」我