【Spring 源码解析】2、从AbstractAutowireCapableBeanFactory.createBean()方法看Bean的生命周期

一、Bean生命周期源码

BeanFactory获取Bean的时候,如果缓存中没有并且父Bean工厂也没有的时候会执行创建Bean的操作,主要逻辑是在AbstractAutowireCapableBeanFactorycreateBean()方法中:

@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
		throws BeanCreationException {

	if (logger.isTraceEnabled()) {
		logger.trace("Creating instance of bean '" + beanName + "'");
	}
	// 1. 创建BeanDefinition 
	RootBeanDefinition mbdToUse = mbd;

	// Make sure bean class is actually resolved at this point, and
	// clone the bean definition in case of a dynamically resolved Class
	// which cannot be stored in the shared merged bean definition.
	Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
	if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
		mbdToUse = new RootBeanDefinition(mbd);
		mbdToUse.setBeanClass(resolvedClass);
	}

	// Prepare method overrides.
	//2. lookup-method和replace-method检测
	try {
		mbdToUse.prepareMethodOverrides();
	}
	catch (BeanDefinitionValidationException ex) {
		throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
				beanName, "Validation of method overrides failed", ex);
	}

	try {
		// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
		//3. InstantiationAwareBeanPostProcessor触发
		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. 调用doCreateBean()方法创建Bean
		Object beanInstance = doCreateBean(beanName, mbdToUse, args); 
		if (logger.isTraceEnabled()) {
			logger.trace("Finished creating instance of bean '" + beanName + "'");
		}
		return beanInstance;
	}
	catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
		// A previously detected exception with proper bean creation context already,
		// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
		throw ex;
	}
	catch (Throwable ex) {
		throw new BeanCreationException(
				mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
	}
}
1. 创建BeanDefinition

首先是调用resolveBeanClass()方法保证bean的类型已被加载。

Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
	mbdToUse = new RootBeanDefinition(mbd);
	mbdToUse.setBeanClass(resolvedClass);
}
2. lookup-method和replace-method检测
mbdToUse.prepareMethodOverrides();

此部分用于检测lookup-method标签配置和replace-method配置的方法是否存在。如果不存在直接标记一下,省去了对方法参数的解析过程,直接调用即可。

3. InstantiationAwareBeanPostProcessor触发

这里会给后置处理器通过修改BeanDefinition偷换Bean的机会:

// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
    return bean;
}

看一下resolveBeforeInstantiation()方法,在这里触发的是其postProcessBeforeInitializationpostProcessAfterInstantiation方法。:

protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
    Object bean = null;
    if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
        // Make sure bean class is actually resolved at this point.
        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;
}

从这里可以看出,如果InstantiationAwareBeanPostProcessor返回的不是空,那么将不会继续执行剩下的Spring初始化流程,此接口用于初始化自定义的bean,主要是在Spring内部使用。也就是说,如果这里bean已经被偷换了,那么直接返回,不用执行下面的doCreateBean()方法了

4. 调用doCreateBean()方法创建Bean

如果前面的Bean没有被修改,那么执行真正的创建Bean的方法doCreateBean():

Object beanInstance = doCreateBean(beanName, mbdToUse, args);
return beanInstance;
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
		throws BeanCreationException {

	// Instantiate the bean.
	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;
	}

	// Allow post-processors to modify the merged bean definition.
	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;
		}
	}

	// Eagerly cache singletons to be able to resolve circular references
	// even when triggered by lifecycle interfaces like BeanFactoryAware.
	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));
	}

	// Initialize the bean instance.
	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.");
				}
			}
		}
	}

	// Register bean as disposable.
	try {
		registerDisposableBeanIfNecessary(beanName, bean, mbd);
	}
	catch (BeanDefinitionValidationException ex) {
		throw new BeanCreationException(
				mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
	}

	return exposedObject;
}
4.1 创建Bean实例

this.factoryBeanInstanceCache.remove(beanName) 先移除缓存中的同名。
factoryBeanInstanceCache是一个ConcurrentMap:ConcurrentMap<String, BeanWrapper> factoryBeanInstanceCache = new ConcurrentHashMap<>();

// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
	instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
	instanceWrapper = createBeanInstance(beanName, mbd, args);
}

然后调用createBeanInstance(beanName, mbd, args)创建bean实例:

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
	// Make sure bean class is actually resolved at this point.
	Class<?> beanClass = resolveBeanClass(mbd, beanName);

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

	Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
	if (instanceSupplier != null) {
		return obtainFromSupplier(instanceSupplier, beanName);
	}

	if (mbd.getFactoryMethodName() != null) {
		return instantiateUsingFactoryMethod(beanName, mbd, args);
	}

	// Shortcut when re-creating the same bean...
	boolean resolved = false;
	boolean autowireNecessary = false;
	if (args == null) {
		synchronized (mbd.constructorArgumentLock) {
			if (mbd.resolvedConstructorOrFactoryMethod != null) {
				resolved = true;
				autowireNecessary = mbd.constructorArgumentsResolved;
			}
		}
	}
	if (resolved) {
		if (autowireNecessary) {
			return autowireConstructor(beanName, mbd, null, null);
		}
		else {
			return instantiateBean(beanName, mbd);
		}
	}

	// Candidate constructors for autowiring?
	Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
	if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
			mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
		return autowireConstructor(beanName, mbd, ctors, args);
	}

	// Preferred constructors for default construction?
	ctors = mbd.getPreferredConstructors();
	if (ctors != null) {
		return autowireConstructor(beanName, mbd, ctors, null);
	}

	// No special handling: simply use no-arg constructor.
	return instantiateBean(beanName, mbd);
}

createBeanInstance的创建过程又分为以下几种情况:
(1)工厂bean:

调用instantiateUsingFactoryMethod方法:

protected BeanWrapper instantiateUsingFactoryMethod(
  String beanName, RootBeanDefinition mbd, Object[] explicitArgs) {
  return new ConstructorResolver(this).instantiateUsingFactoryMethod(beanName, mbd, explicitArgs);
}

(2)构造器自动装配

// Need to determine the constructor...
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null ||
  mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
    //配置了<constructor-arg>子元素
  mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args))  {
  return autowireConstructor(beanName, mbd, ctors, args);
}

先根据determineConstructorsFromBeanPostProcessors()方法决定构造函数,determineConstructorsFromBeanPostProcessors()源码:

protected Constructor<?>[] determineConstructorsFromBeanPostProcessors(Class<?> beanClass, String beanName) {
  if (beanClass != null && hasInstantiationAwareBeanPostProcessors()) {
      for (BeanPostProcessor bp : getBeanPostProcessors()) {
          if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
              SmartInstantiationAwareBeanPostProcessor ibp = 
                  (SmartInstantiationAwareBeanPostProcessor) bp;
              Constructor<?>[] ctors = ibp.determineCandidateConstructors(beanClass, beanName);
              if (ctors != null) {
                  return ctors;
              }
          }
      }
  }
  return null;
}

可见是由SmartInstantiationAwareBeanPostProcessor决定的,默认是没有配置这种东西的。

之后就是判断bean的自动装配模式,可以通过如下方式配置:

<bean id="student" class="base.Student" primary="true" autowire="default" />

autowire共有以下几种选项:

  • no: 默认的,不进行自动装配。在这种情况下,只能通过ref方式引用其它bean。
  • byName: 根据bean里面属性的名字在BeanFactory中进行查找并装配。
  • byType: 按类型。
  • constructor: 以byType的方式查找bean的构造参数列表。
  • default: 由父bean决定。

然后调用autowireConstructor()返回bean实例,autowireConstructor调用的是ConstructorResolver.autowireConstructor(),此方法主要做了两件事:

  • 得到合适的构造器对象。
  • 根据构造器参数的类型去BeanFactory查找相应的bean。

(3)默认的无参构造函数

一行代码,很简单:

// No special handling: simply use no-arg constructor.
return instantiateBean(beanName, mbd);
4.2 MergedBeanDefinitionPostProcessor

调用applyMergedBeanDefinitionPostProcessors() 方法合并BeanDefinition的后置处理器。

// Allow post-processors to modify the merged bean definition.
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;
	}
}
4.3 创建早期引用对象

调用addSingletonFactory()方法,暴露bean的EarlyBeanReferenced,主要是为了循环引用,比如a中包含b,b中包含a,这样可以先把引用暴露出来,下面才会调用注入。这里添加一个ObjectFactory作为bean的生产方式。但是注意这里的bean其实并没有进行属性注入。

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

addSingletonFactory()方法:

protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
	Assert.notNull(singletonFactory, "Singleton factory must not be null");
	synchronized (this.singletonObjects) {
		if (!this.singletonObjects.containsKey(beanName)) {
			this.singletonFactories.put(beanName, singletonFactory);
			this.earlySingletonObjects.remove(beanName);
			this.registeredSingletons.add(beanName);
		}
	}
}

getEarlyBeanReference()方法:

protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
	Object exposedObject = bean;
	if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
		for (SmartInstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().smartInstantiationAware) {
			exposedObject = bp.getEarlyBeanReference(exposedObject, beanName);
		}
	}
	return exposedObject;
}
4.4 属性解析

调用populateBean()方法,填充bean中的引用内容,包括注解的字段,spel表达式等等。

protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
    //所有<property>的值
    PropertyValues pvs = mbd.getPropertyValues();

    if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
            mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
        MutablePropertyValues newPvs = new MutablePropertyValues(pvs);

        // Add property values based on autowire by name if applicable.
        if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
            autowireByName(beanName, mbd, bw, newPvs);
        }

        // Add property values based on autowire by type if applicable.
        if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
            autowireByType(beanName, mbd, bw, newPvs);
        }

        pvs = newPvs;
    }
    //设值
    applyPropertyValues(beanName, mbd, bw, pvs);
}

autowireByName()方法:

protected void autowireByName(
        String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
    //返回所有引用(ref="XXX")的bean名称
    String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
    for (String propertyName : propertyNames) {
        if (containsBean(propertyName)) {
             //从BeanFactory获取
            Object bean = getBean(propertyName);
            pvs.add(propertyName, bean);
            registerDependentBean(propertyName, beanName);
        }
    }
}

autowireByType也是同样的套路,所以可以得出结论: autowireByName和autowireByType方法只是先获取到引用的bean,真正的设值是在applyPropertyValues()中进行的。

Spring判断一个属性可不可以被设置(存不存在)是通过java bean的内省操作来完成的,也就是说,属性可以被设置的条件是此属性拥有public的setter方法,并且注入时的属性名应该是setter的名字。

4.5 初始化

此处的initializeBean()方法初始化指的是bean已经构造完成,执行诸如调用其init方法的操作,init-method,@post-process注解(JSR标准),initializingBean接口,PostProcessor的前后bean初始化方法等等。

protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
    if (System.getSecurityManager() != null) {
        AccessController.doPrivileged(new PrivilegedAction<Object>() {
            @Override
            public Object run() {
                invokeAwareMethods(beanName, bean); //(1)Aware方法触发
                return null;
            }
        }, getAccessControlContext());
    }
    else {
        invokeAwareMethods(beanName, bean);
    }

    Object wrappedBean = bean;
    if (mbd == null || !mbd.isSynthetic()) {
        //(2)初始化前置BeanPostProcessor触发
        wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
    }
	//(3)调用init方法:
    invokeInitMethods(beanName, wrappedBean, mbd);

    if (mbd == null || !mbd.isSynthetic()) {
    	//(4)初始化后置BeanPostProcessor触发
        wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
    }
    return wrappedBean;
}

主要的操作步骤一目了然。

(1)Aware方法触发
调用inokeAwareMethods()方法,实现beanFactory相关的通知,也就是aware方法。BeanNameAware、BeanFactoryAware、BeanClassLoaderAware。

(2)初始化前置BeanPostProcessor触发
调用Bean处理器的初始化前处理方法applyBeanPostProcessorsBeforeInitialization()。PostConstruct注解就是在此处理:

(3)调用init方法
在XML配置中,bean可以有一个init-method属性来指定初始化时调用的方法。从原理来说,其实就是一个反射调用。不过注意这里有一个InitializingBean的概念。

此接口只有一个方法:

void afterPropertiesSet() throws Exception;

如果我们的bean实现了此接口,那么此方法会首先被调用。此接口的意义在于: 当此bean的所有属性都被设置(注入)后,给bean一个利用现有属性重新组织或是检查属性的机会。感觉和init方法有些冲突,不过此接口在Spring被广泛使用。

(4)初始化后置BeanPostProcessor触发
调用Bean处理器的初始化后的处理方法applyBeanPostProcessorsAfterInitialization() ,执行Bean处理器的初始化后处理。

4.6 暴露早期引用对象

如果允许提前暴露,调用getSingleTon()方法,将完全体的Bean注入到beanFactory中:

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);
				}
			}
		}
	}
}
4.7 注册销毁方法

调用 registerDisposableBeanIfNecessary()方法,注册Bean的销毁方法。此处包括 destroy-method,还有JSR中的PreDestroy注解等。 然后返回Bean实例。

二、Bean生命周期图示

Bean

Bean


THE END.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值