图中是我整理的相关Bean创建流程,主要可以分为三层:
下面将从以下几个方面来总结Bean创建的整个流程:
通过上面图的流程分析,我们看到Bean的创建过程,大致分为三个层次,下面分别看下者三个层次做了什么事情.
AbstractBeanFactory的继承体系
AbstractBeanFactory主要作用如下:
这就不难理解为什么要在,DefaultListableBeanFactory.preInstantiateSingletons()方法中触发用户定义的所有Bean的初始化了,因为DefaultListableBeanFactory持有了当前容器中用户定义的Bean的BeanDefinition信息和所有的beanName信息,那么只需要遍历,调用AbstractBeanFactory.getBean(beanName)就可以完成所有bean的创建了
AbstractBeanFactory类中Bean创建流程主要在doGetBean方法中,该方法主要逻辑如下:
private final Set<String> alreadyCreated = Collections.newSetFromMap(new ConcurrentHashMap<>(256));
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
//1转换Bean名称
final String beanName = transformedBeanName(name);
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
//2.1检查是否循环依赖,如果是,先获取依赖Bean的引用
....
}else{
//2.2正常创建
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// 如果当前BeanFactory设置了父BeanFactory,交由父BeanFactory创建Bean
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
//..父BeanFactory创建bean
}
//将beanName放到alreadyCreated集合,在该层中标记beanName对应的Bean正在创建 ,这个缓存和循环依赖没有关系
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}
//获取当前beanName对应的BeanDefinition类
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
//处理@DependsOn 依赖的bean,也是根据beanName加载对应bean的流程
}
//singleton类型bean创建
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);
}else if (mbd.isPrototype()) {
//prototype类型Bean创建
}else{
//scope 类型Bean创建
}
// 是否需要根据给定的类型转化bean
if (requiredType != null && !requiredType.isInstance(bean)) {
try {
T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
if (convertedBean == null) {
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
return convertedBean;
}
catch (TypeMismatchException ex) {
if (logger.isDebugEnabled()) {
logger.debug("Failed to convert bean '" + name + "' to required type '" +
ClassUtils.getQualifiedName(requiredType) + "'", ex);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}
return (T) bean;
}
}
用于存放当前已经开始创建Bean的beanname,因为在多线程的情况下,如果要是在创建Bean的过程中,有可能有的线程还在通过DefaultListableBeanFactory往容器内注册Bean的BeanDefinition,而Bean的初始化开始时,是在DefaultListableBeanFactory通过遍历beanDefinitionNames所有beanName进行注册Bean的,所以有可能会造成iterator不安全.
伪代码如下:
//容器ApplicationContext触发Bean的初始化流程
Map<String, BeanDefinition> beanDefinitionMap = new HashMap();
List<String> beanDefinitionNames = new ArrayList();
//加载了 BeanDefinition
....
preInstantiateSingletons(){
//开始初始化
for(String beanName : this.beanDefinitionNames){
getBean(beanName)
}
}
//这时如果并发的再注册Bean,那么beanDefinitionNames,动态添加将是不安全的.
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);
}
在singleton类型分之,主要有这两个函数调用:
接下来看getSingleton方法.
以下是getSingleton方法代码:
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(beanName, "Bean name must not be null");
synchronized (this.singletonObjects) {
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
if (this.singletonsCurrentlyInDestruction) {
throw new BeanCreationNotAllowedException(beanName,
"Singleton bean creation not allowed while singletons of this factory are in destruction " +
"(Do not request a bean from a BeanFactory in a destroy method implementation!)");
}
if (logger.isDebugEnabled()) {
logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
}
beforeSingletonCreation(beanName);
boolean newSingleton = false;
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<>();
}
try {
singletonObject = singletonFactory.getObject();
newSingleton = true;
}
catch (IllegalStateException ex) {
// Has the singleton object implicitly appeared in the meantime ->
// if yes, proceed with it since the exception indicates that state.
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
throw ex;
}
}
catch (BeanCreationException ex) {
if (recordSuppressedExceptions) {
for (Exception suppressedException : this.suppressedExceptions) {
ex.addRelatedCause(suppressedException);
}
}
throw ex;
}
finally {
if (recordSuppressedExceptions) {
this.suppressedExceptions = null;
}
afterSingletonCreation(beanName);
}
if (newSingleton) {
addSingleton(beanName, singletonObject);
}
}
return singletonObject;
}
}
getSingleton方法内容比较简单,主要分为以下内容:
其中ObjectFactory.getObject()方法就是AbstractBeanFactory中的createBean方法,是创建Bean实例的具体方法.
另外,DefaultSingletonBeanRegistry中还维护了spring 中bean创建过程中使用到的三个缓存集合:
后面会讲到这三个集合是如何配合使用的.
再贴一次上面的流程图:
真正创建Bean时,经过以下几步:
下面对每一步进行分析.
我们看下该类的注释:
This interface is a special purpose interface, mainly for
* internal use within the framework. It is recommended to implement the plain
* {@link BeanPostProcessor} interface as far as possible, or to derive from
* {@link InstantiationAwareBeanPostProcessorAdapter} in order to be shielded
* from extensions to this interface.
InstantiationAwareBeanPostProcessor这个接口是有特殊用途的,主要在spring框架内部使用.
一般推荐推荐使用BeanPostProcessor或InstantiationAwareBeanPostProcessorAdapter来实现增强bean的功能.
接口定义代码:
public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
@Nullable
default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
return null;
}
default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
return true;
}
@Nullable
default PropertyValues postProcessPropertyValues(
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
return pvs;
}
}
方法说明:
特别注意:
spring中AOP实现AspectJAwareAdvisorAutoProxyCreator,就是该接口的子类.
Bean对应Class实例化方式有以下几种:
在springBean创建过程中,对属性依赖注入,支持三种情况:
Bean初始化接口主要分为三类:
执行顺序:
Aware接口->BeanPostProcessor.postProcessBeforeInitialization->InitializingBean接口->BeanPostProcessor.postProcessAfterInitialization
为什么是这个顺序?
Bean在创建过程中会执行,以下三个Aware接口的调用:
在Bean创建的过程的最后阶段,Spring会把Bean包装成DisposableBeanAdapter,注册到DefaultSingletonBeanRegistry中的Map
DisposableBeanAdapter.destroy方法代码如下:
@Override
public void destroy() {
if (!CollectionUtils.isEmpty(this.beanPostProcessors)) {
for (DestructionAwareBeanPostProcessor processor : this.beanPostProcessors) {
processor.postProcessBeforeDestruction(this.bean, this.beanName);
}
}
if (this.invokeDisposableBean) {
if (logger.isDebugEnabled()) {
logger.debug("Invoking destroy() on bean with name '" + this.beanName + "'");
}
try {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
((DisposableBean) this.bean).destroy();
return null;
}, this.acc);
}
else {
((DisposableBean) this.bean).destroy();
}
}
catch (Throwable ex) {
String msg = "Invocation of destroy method failed on bean with name '" + this.beanName + "'";
if (logger.isDebugEnabled()) {
logger.warn(msg, ex);
}
else {
logger.warn(msg + ": " + ex);
}
}
}
if (this.destroyMethod != null) {
invokeCustomDestroyMethod(this.destroyMethod);
}
else if (this.destroyMethodName != null) {
Method methodToCall = determineDestroyMethod(this.destroyMethodName);
if (methodToCall != null) {
invokeCustomDestroyMethod(methodToCall);
}
}
}
它会调用bean上定义的destroy-method指定的方法.
以具体例子来说明FactoryBean的原理:
@Component
public class FactoryBeanService implements FactoryBean<AddressService> {
@Override
public AddressService getObject() throws Exception {
System.out.println("AddressService");
return new AddressServiceImpl();
}
@Override
public Class<?> getObjectType() {
return AddressService.class;
}
}
public interface AddressService {
}
public class AddressServiceImpl implements AddressService {
}
当在执行Bean创建流程时,参考第一章部分,会首先创建一个FactoryBeanService对应的Bean,即:
singletonObjects集合中存在:
factoryBeanService-> factoryBeanService 对应的Bean
这是如果通过context.getBean(AddressService.class)或者通过@Autowire在别的Bean中注入AddressService时就会再次走Bean创建流程,创建AddressService对应的Bean,流程如下:
总结:
我们将通过上图来说明以下Spring解决循环依赖的原理.
首先,再次说下Spring三级缓存对应到代码中是,DefaultSingletonBeanRegistry中的:
下面我们通过上图和代码一起结合说明.
首先:循环依赖的代码在AbstractAutowireCapableBeanFactory.doCreateBean中.
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @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);
}
final Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
...
// 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.isDebugEnabled()) {
logger.debug("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) {
...
}
// Register bean as disposable.
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
在每个一个Bean实际创建时,都会执行这段代码:
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isDebugEnabled()) {
logger.debug("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
这块代码的含义的是,将一个ObjectFactory类型放到singletonFactories,即上面的SF-Map.
那么首先分析无循环依赖时,如何创建Bean A,步骤如下
第一步:
将Bean A对应的ObjectFactory对象放到singletonFactories,
第二步:
正常实例化Bean 对应的Class,执行属性注入、初始化接口调用
第三步:
当Bean创建完成,在第一章的总图中,第二张图,即DefaultSingletonBeanRegistry.getSingleton方法中,
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(beanName, "Bean name must not be null");
synchronized (this.singletonObjects) {
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
if (this.singletonsCurrentlyInDestruction) {
throw new BeanCreationNotAllowedException(beanName,
"Singleton bean creation not allowed while singletons of this factory are in destruction " +
"(Do not request a bean from a BeanFactory in a destroy method implementation!)");
}
if (logger.isDebugEnabled()) {
logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
}
beforeSingletonCreation(beanName);
boolean newSingleton = false;
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<>();
}
try {
singletonObject = singletonFactory.getObject();
newSingleton = true;
}
catch (IllegalStateException ex) {
// Has the singleton object implicitly appeared in the meantime ->
// if yes, proceed with it since the exception indicates that state.
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
throw ex;
}
}
catch (BeanCreationException ex) {
if (recordSuppressedExceptions) {
for (Exception suppressedException : this.suppressedExceptions) {
ex.addRelatedCause(suppressedException);
}
}
throw ex;
}
finally {
if (recordSuppressedExceptions) {
this.suppressedExceptions = null;
}
afterSingletonCreation(beanName);
}
if (newSingleton) {
addSingleton(beanName, singletonObject);
}
}
return singletonObject;
}
}
addSingleton(beanName, singletonObject);这步,我们看下代码:
protected void addSingleton(String beanName, Object singletonObject) {
synchronized (this.singletonObjects) {
this.singletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
我们看到,将该bean的对应的beanName从singletonFactories移除,即刚才我们加入的ObjectFactory对象被移除,没有使用到,并且还会移除earlySingletonObjects中对应的内容,虽然也没有添加.
然后将beanName->bean 加入到singletonObjects,即完成当前bean的创建.
总结:
假设现在如图中所示,A依赖B,B依赖A.
那么按照我们上面的流程,假如先创建A,则
那么怎么找A呢?
Spring默认是按类型注入,这里假设我们没有做任何特别设置,那么也是按类型注入,那么将会进行如下步骤:
我们看下getSingleton这个方法:
public Object getSingleton(String beanName) {
return getSingleton(beanName, true);
}
@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}
这时调用的是
getSingleton(String beanName),也就是说调用getSingleton(String beanName, boolean allowEarlyReference)时,allowEarlyReference为true.
我们看下这个方法做了什么:
从这里我们明白了earlySingletonObjects这个缓存的含义:
就是某一个Bean 例如A创建的过程中,由于循环依赖的存在提前需要执行完成一些操作,并且把操作后的对象 加入 Proxy A放到这里,使得当最开始的A属性注入完,可以继续执行后续的操作.
看下ObjectFactory.getObject()操作做了什么:
() -> getEarlyBeanReference(beanName, mbd, bean)
这是我们放入的ObjectFactory, getEarlyBeanReference 逻辑如下:
protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
Object exposedObject = bean;
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
}
}
}
return exposedObject;
}
//SmartInstantiationAwareBeanPostProcessor
default Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
return bean;
}
SmartInstantiationAwareBeanPostProcessor类的getEarlyBeanReference默认是返回传入的Bean.但是,如果SmartInstantiationAwareBeanPostProcessor
开启了AOP功能,并且当前Bean需要AOP功能,那么就会在AbstractAutoProxyCreator类中,对当前Bean进行代理包装,并将当前beanName加入earlyProxyReferences集合,返回代理类.
private final Set<Object> earlyProxyReferences = Collections.newSetFromMap(new ConcurrentHashMap<>(16));
@Override
public Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (!this.earlyProxyReferences.contains(cacheKey)) {
this.earlyProxyReferences.add(cacheKey);
}
return wrapIfNecessary(bean, beanName, cacheKey);
}
这时earlySingletonObjects中就会存在 beanName a->ProxyA
那么在原先A属性属性注入完,会怎么处理?
在初始化步骤,spring会执行BeanPostProcessor的postProcessAfterInitialization.时,一定会执行到AbstractAutoProxyCreator的postProcessAfterInitialization方法
private final Set<Object> earlyProxyReferences = Collections.newSetFromMap(new ConcurrentHashMap<>(16));
@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) throws BeansException {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (!this.earlyProxyReferences.contains(cacheKey)) {
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
而earlyProxyReferences就保存了之前在getEarlyBeanReference生成的ProxyA对应的beanName,那么就会直接放回当前bean.
这就是earlySingletonObjects存在的价值,为了解决含有代理逻辑的循环依赖解决方案.
下面用一个小图总结一下:
首先为A创建ObjectFactory 对象放入singletonFactories,所有正常单例bean都有这一步
如果存在循环依赖,则会被调用ObjectFactory.getObject()
当创建Bean流程完成后,