Spring容器初始化最后,完成对扫描出的BeanDefinition初始化,并存放到map容器中。
首先从doGetBean开始分析, 此时容器已初始化完成, 开始执行bean的初始化
// org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean
protected <T> T doGetBean(
final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
throws BeansException {
...
Object bean;
// 此处从缓存中获取对象, 如果对象已经被初始化, 则直接返回; 获取对象优先顺序:
// 1.singletonsCurrentlyInCreation存储当前正在创建的bean
// 2.earlySingletonObjects存储bean的早期依赖 已被实例化 但属性没有赋值的bean
// 3.singletonFactories存储创建bean的工厂 在此可完成创建代理对象
// 如果需要从工厂创建bean, 在创建完成后, 添加到earlySingletonObjects, 并且从singletonFactories中移除
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
...
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
} else {
try {
// Create bean instance.
if (mbd.isSingleton()) {
// 此处添加了一个匿名类对象,待会儿会调用
sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
...
}
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
...
}
catch (BeansException ex) {
...
}
}
...
return (T) bean;
}
第一个getSingleton,从缓存中获取,第一次获取为null
// 从缓存中获取对象, 如果对象已经被初始化, 则直接返回
// org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
Object singletonObject = this.singletonObjects.get(beanName); // 一级缓存 完整的bean
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(); // 三级缓存 Factory 可能需要代理
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
return (singletonObject != NULL_OBJECT ? singletonObject : null);
}
第二个getSingleton
// org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
// 判断是否为null
Assert.notNull(beanName, "'beanName' must not be null");
synchronized (this.singletonObjects) {
// 首先从单例对象Map中获取bean
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 + "'");
}
// 判断对象是否存在于singletonsCurrentlyInCreation, 如是报异常
beforeSingletonCreation(beanName);
boolean newSingleton = false;
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<Exception>();
}
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;
}
// 从当前创建对象池Set中移除当前beanName
afterSingletonCreation(beanName);
}
if (newSingleton) {
// 执行了以下操作: 标记对象已创建完成
// singletonObjects.put 添加到一级缓存张
// singletonFactories.remove
// earlySingletonObjects.remove
// registeredSingletons.add
addSingleton(beanName, singletonObject);
}
}
return (singletonObject != NULL_OBJECT ? singletonObject : null);
}
}
singletonFactory.getObject()代码解析
// org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
...
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
...
return beanInstance;
}
// org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
throws BeanCreationException {
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
// 通过构造方法实例化bean,并存放到wrapper包装对象中 ----------完成实例化
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.
// 判断db是否为单例, 并且容器是否允许循环引用, 并且对象不在当前创建池中
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");
}
// 执行一下步骤
// singletonFactories.put 添加到一级缓存中
// earlySingletonObjects.remove
// registeredSingletons.add
// 这里也是构造了一个匿名类对象 在
addSingletonFactory(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
// 这个方法在三级缓存处, 从第三级向第二级转存的时候调用
// 获取对象的早期依赖, 此时对象已被实例化, 但是属性未被赋值
// 方法内通过beanPostProcessor可以完成代理
return getEarlyBeanReference(beanName, mbd, bean);
}
});
}
// Initialize the bean instance.
Object exposedObject = bean;
try {
// 为对象(包含早期依赖对象)属性赋值
populateBean(beanName, mbd, instanceWrapper);
if (exposedObject != null) {
// 此方法内对Spring部分扩展功能进行回调
// BeanNameAware / BeanFactoryAware / BeanPostProcessor.postProcessBeforeInitialization / InitializingBean.afterPropertiesSet / initMethod / BeanPostProcessor.postProcessAfterInitialization
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<String>(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 {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
此方法可以完成对对象的代理,如果使用了AOP,通过AnnotationAwareAspectJAutoProxyCreator父类的getEarlyBeanReference方法产生代理
// org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#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) { // 包含不限于AnnotationAwareAspectJAutoProxyCreator
SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
}
}
}
return exposedObject;
}
// org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#getEarlyBeanReference
public Object getEarlyBeanReference(Object bean, String beanName) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (!this.earlyProxyReferences.contains(cacheKey)) {
this.earlyProxyReferences.add(cacheKey);
}
return wrapIfNecessary(bean, beanName, cacheKey);
}
// org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#wrapIfNecessary
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
...
// Create proxy if we have advice.
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
// 生成代理对象
Object proxy = createProxy(
bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
只有一级缓存
Map中包含了初始化完毕的bean和未完成的bean, 当有线程获取bean时, 会有问题
只有二级缓存
一个Map存放了初始化完成的bean, 一个存放了未完成的bean, 但是无法解决aop下需要代理的bean
两级缓存
在需要代理的情况下, 一级缓存就要放入代理对象, 二级缓存存放初始化完成的对象. 但是无法解决循环依赖的问题, 因为一级中放入的代理对象如果依赖的当前对象, 再次注入当前对象的代理对象时, 会产生新的代理对象, 会导致两个对象不一致, 解决不了循环依赖
前置条件
A->B B->A Spring先装载A, 后装载B
结论
如果A为prototype, 无论B是否为单例, 循环依赖都会出错, 因为在初始化B时, 发现依赖A, 会注入一个新的A, 出现死循环;
如果A为singleton, 无论B是否为单例, 循环依赖都没有问题, 即便B不是单例, B实例化时, 注入已经实例化的A, 初始化仍然能够完成.