Spring启动流程(三)之Bean的初始化(非懒加载的单例Bean)

上一篇Spring启动流程(二)之Spring加载Bean Definition的流程主要分析了如何从xml配置中读取Bean的配置,然后加载生成对应的Bean Definition。

主要代码为:

// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

obtainFreshBeanFactory()最终返回一个存放了Bean Definition信息的Bean工厂——DefaultListableBeanFactory。

1、准备DefaultListableBeanFactory

后面的几步,也都是往DefaultListableBeanFactory里加东西,让它可扩展。(如何做到可扩展可单独成篇叙述)

// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);


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

2、初始化Bean实例,返回Bean Wrapper

到这一步,准备工作做完了,扩展也设置好了,真正的开始实例化Bean对象了:

// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// Instantiate all remaining (non-lazy-init) singletons.
beanFactory.preInstantiateSingletons();

Spring默认创建的实例是单例的,代码从AbstractBeanFactory.doGetBean()开始,下面是部分代码

// Create bean instance.
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);
}

上面代码看createBean方法,这个方法是AbstractAutowireCapableBeanFactory中的。

看createBean的方法注释

Central method of this class: creates a bean instance,populates the bean instance, applies post-processors

可以知道,这个方法的核心方法是:创建bean实例、填充bean 实例(填充实例内部引用的其他实例)、应用扩展方法

createBean内部:

try {
	// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
	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) {
	// 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);
}

上面代码是createBean的部分内容。忽略try catch,

Object bean = resolveBeforeInstantiation(beanName, mbdToUse);

上面这行是调用初始化前的扩展点。

接着看doCreateBean方法,方法注释为

Actually create the specified bean. Pre-creation processing has already happened at this point, e.g. checking postProcessBeforeInstantiation callbacks.
Differentiates between default bean instantiation, use of a factory method, and autowiring a constructor.

 这里说bean实例开始真正创建了,==||

if (instanceWrapper == null) {
	instanceWrapper = createBeanInstance(beanName, mbd, args);
}

查看createBeanInstance方法签名和注释

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)

Create a new instance for the specified bean, using an appropriate instantiation strategy: factory method, constructor autowiring, or simple instantiation.

可知,这里面做的应该就是创建bean实例的勾当了吧?!

而且这里说明了有三种初始化策略:使用工厂方法实例化、使用构造方法实例化、简单初始化(默认构造函数)。

涉及到的类和接口如下图:

Spring启动流程(三)之Bean的初始化(非懒加载的单例Bean)_第1张图片

最终会使用反射API来初始化或者CglibAPI来创建子类然后初始化

ReflectionUtils.makeAccessible(ctor);
return (KotlinDetector.isKotlinReflectPresent() && KotlinDetector.isKotlinType(ctor.getDeclaringClass()) ?
		KotlinDelegate.instantiateClass(ctor, args) : ctor.newInstance(args));
// Must generate CGLIB subclass...
return new CglibSubclassCreator(bd, owner).instantiate(ctor, args);

如何决定使用哪种方式来实例化呢?可以看看SimpleInstantiationStrategy类中的instantiate方法。

@Override
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
// Don't override the class with CGLIB if no overrides.
if (!bd.hasMethodOverrides()) {
	Constructor constructorToUse;
	synchronized (bd.constructorArgumentLock) {
		constructorToUse = (Constructor) bd.resolvedConstructorOrFactoryMethod;
		if (constructorToUse == null) {
			final Class clazz = bd.getBeanClass();
			if (clazz.isInterface()) {
				throw new BeanInstantiationException(clazz, "Specified class is an interface");
			}
			try {
				if (System.getSecurityManager() != null) {
					constructorToUse = AccessController.doPrivileged(
							(PrivilegedExceptionAction>) clazz::getDeclaredConstructor);
				}
				else {
					constructorToUse = clazz.getDeclaredConstructor();
				}
				bd.resolvedConstructorOrFactoryMethod = constructorToUse;
			}
			catch (Throwable ex) {
				throw new BeanInstantiationException(clazz, "No default constructor found", ex);
			}
		}
	}
	return BeanUtils.instantiateClass(constructorToUse);
}
else {
	// Must generate CGLIB subclass.
	return instantiateWithMethodInjection(bd, beanName, owner);
}

Bean definition中没有overrides的方法,就会使用反射API,否则使用CGLIB 的API。

不管是使用上面哪种策略,最终产生的实例是一个BeanWrapper。一个用来包装Bean实例的对象。

为什么要包装一下呢?

3、填充Bean实例的属性值

继续看看获取到BeanWrapper后Spring做的事情。

再回到AbstractAutowireCapableBeanFactory的doCreateBean方法

if (instanceWrapper == null) {
	instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final 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;
	}
}

createBeanInstance方法上面已经分析过了,会通过反射或者Cgilib创建子类实例化一个BeanWrapper返回。

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

populateBean方法开始填充我们刚刚生成的BeanWrapper实例的属性值。

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

上面的代码会将By Name和By Type注入的属性给newPvs——MutablePropertyValues类型。

populateBean最后执行applyPropertyValues方法

if (pvs != null) {
	applyPropertyValues(beanName, mbd, bw, pvs);
}

 applyPropertyValues关键代码如下:

// Set our (possibly massaged) deep copy.
try {
	bw.setPropertyValues(new MutablePropertyValues(deepCopy));
}
catch (BeansException ex) {
	throw new BeanCreationException(
			mbd.getResourceDescription(), beanName, "Error setting property values", ex);
}

 上面的setPropertyValues内部会循环调用setPropertyValue,即遍历属性,逐个拷贝。

@Override
public void setPropertyValue(PropertyValue pv) throws BeansException {
	PropertyTokenHolder tokens = (PropertyTokenHolder) pv.resolvedTokens;
	if (tokens == null) {
		String propertyName = pv.getName();
		AbstractNestablePropertyAccessor nestedPa;
		try {
			nestedPa = getPropertyAccessorForPropertyPath(propertyName);
		}
		catch (NotReadablePropertyException ex) {
			throw new NotWritablePropertyException(getRootClass(), this.nestedPath + propertyName,
					"Nested property in path '" + propertyName + "' does not exist", ex);
		}
		tokens = getPropertyNameTokens(getFinalPath(nestedPa, propertyName));
		if (nestedPa == this) {
			pv.getOriginalPropertyValue().resolvedTokens = tokens;
		}
		nestedPa.setPropertyValue(tokens, pv);
	}
	else {
		setPropertyValue(tokens, pv);
	}
}

nestedPa.setPropertyValue方法内部,主要是通过反射设置属性值。

BeanWrapperImpl.setValue():

@Override
public void setValue(final @Nullable Object value) throws Exception {
	final Method writeMethod = (this.pd instanceof GenericTypeAwarePropertyDescriptor ?
			((GenericTypeAwarePropertyDescriptor) this.pd).getWriteMethodForActualAccess() :
			this.pd.getWriteMethod());
	if (System.getSecurityManager() != null) {
		AccessController.doPrivileged((PrivilegedAction) () -> {
			ReflectionUtils.makeAccessible(writeMethod);
			return null;
		});
		try {
			AccessController.doPrivileged((PrivilegedExceptionAction) () ->
					writeMethod.invoke(getWrappedInstance(), value), acc);
		}
		catch (PrivilegedActionException ex) {
			throw ex.getException();
		}
	}
	else {
		ReflectionUtils.makeAccessible(writeMethod);
		writeMethod.invoke(getWrappedInstance(), value);
	}
} 
  

4、Aware注入

上面通过反射填充了属性值后,会接着执行

exposedObject = initializeBean(beanName, exposedObject, mbd);

该方法的代码如下:

protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
	AccessController.doPrivileged((PrivilegedAction) () -> {
		invokeAwareMethods(beanName, bean);
		return null;
	}, getAccessControlContext());
}
else {
	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;
} 
  

上面的代码就是Spring在初始化bean时的扩展点的调用,下面逐个看下:

invokeAwareMethods

private void invokeAwareMethods(final String beanName, final Object bean) {
if (bean instanceof Aware) {
	if (bean instanceof BeanNameAware) {
		((BeanNameAware) bean).setBeanName(beanName);
	}
	if (bean instanceof BeanClassLoaderAware) {
		ClassLoader bcl = getBeanClassLoader();
		if (bcl != null) {
			((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
		}
	}
	if (bean instanceof BeanFactoryAware) {
		((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
	}
}
}

看到这里判断,如果bean是BeanNameAware接口的实现类会调用setBeanName方法、如果bean是BeanClassLoaderAware接口的实现类会调用setBeanClassLoader方法、如果是BeanFactoryAware接口的实现类会调用setBeanFactory方法,注入对应的属性值。

调用BeanPostProcessor的postProcessBeforeInitialization方法

Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
	wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
@Override
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
		throws BeansException {

	Object result = existingBean;
	for (BeanPostProcessor processor : getBeanPostProcessors()) {
		Object current = processor.postProcessBeforeInitialization(result, beanName);
		if (current == null) {
			return result;
		}
		result = current;
	}
	return result;
}

遍历每个BeanPostProcessor接口实现,调用postProcessBeforeInitialization方法,调用时机是什么?

调用初始化方法

invokeInitMethods(beanName, wrappedBean, mbd);
protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd)
	throws Throwable {

boolean isInitializingBean = (bean instanceof InitializingBean);
if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
	if (logger.isTraceEnabled()) {
		logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
	}
	if (System.getSecurityManager() != null) {
		try {
			AccessController.doPrivileged((PrivilegedExceptionAction) () -> {
				((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)) &&
			!mbd.isExternallyManagedInitMethod(initMethodName)) {
		invokeCustomInitMethod(beanName, bean, mbd);
	}
}
} 
  

初始化的时候,如果实现了InitializingBean接口或者自定义init方法,这里会执行到。

调用BeanPostProcessor的postProcessAfterInitialization方法

wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
@Override
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;
}

上面的方法遍历BeanPostProcessor,调用postProcessAfterInitialization方法。

注册需要执行销毁方法的Bean

registerDisposableBeanIfNecessary(beanName, bean, mbd);
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()) {
			// Register a DisposableBean implementation that performs all destruction
			// work for the given bean: DestructionAwareBeanPostProcessors,
			// DisposableBean interface, custom destroy method.
			registerDisposableBean(beanName,
					new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
		}
		else {
			// A bean with a custom scope...
			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, getBeanPostProcessors(), acc));
		}
	}
}

第三行要求注册销毁的Bean不是原型,并且满足requiresDestruction方法

protected boolean requiresDestruction(Object bean, RootBeanDefinition mbd) {
	return (bean.getClass() != NullBean.class &&
			(DisposableBeanAdapter.hasDestroyMethod(bean, mbd) || (hasDestructionAwareBeanPostProcessors() &&
					DisposableBeanAdapter.hasApplicableProcessors(bean, getBeanPostProcessors()))));
}

可以被销毁的bean需要满足:

1、首先,bean不为空,然后2、3有一个满足即可

2、bean有destroy方法

3、bean对应的beanFactory持有DestructionAwareBeanPostProcessor接口的实现类,并且bean有destruction-aware post-processors,即DestructionAwareBeanPostProcessor这个接口的实现。

满足以上条件才能注册为可销毁的Bean

registerDisposableBean(beanName,new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
public void registerDisposableBean(String beanName, DisposableBean bean) {
	synchronized (this.disposableBeans) {
		this.disposableBeans.put(beanName, bean);
	}
}

容器销毁的时候,会遍历disposableBeans,逐一执行销毁方法。

Spring Bean 初始化总结

图像来源:https://www.cnblogs.com/xrq730/p/6363055.html

Spring启动流程(三)之Bean的初始化(非懒加载的单例Bean)_第2张图片

文章参考五月的仓颉大佬的博客,并结合自己的实践而成。

自己目前debug了三遍源码,觉得只有自己debug到源码去看,才能有一个清晰的认识,看博客和自己debug是两码事。

你可能感兴趣的:(Spring)