上一节,我们从宏观的角度分析了下bean实例化的预处理步骤,这一节,我们重点来研究获取单例bean,之前分析过的代码就不在做分析了
我们直接从dogetBean说起一起再看下下面的这段代码
Object sharedInstance = getSingleton(beanName);
//当sharedInstance不为null.并且args参数为null的时候,说明就是想获取bean,不是创建bean,这个时候,就会调用getObjectForBeanInstance
if (sharedInstance != null && args == null) {
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
#AbstractBeanFactory
protected Object getObjectForBeanInstance(
Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
// 如果name不为空,并且name是以&开头,说明就是工厂bean
if (BeanFactoryUtils.isFactoryDereference(name)) {
//如果此时的工厂bean是个null,直接返回
if (beanInstance instanceof NullBean) {
return beanInstance;
}
//再次判断beanInstance是否是工厂bean,如果不是,直接抛出异常
if (!(beanInstance instanceof FactoryBean)) {
throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());
}
}
//走到这里,可以判断此时的bean有可能是一个普通的bean,有可能是一个工厂bean,如果是普通bean,直接返回
//如果是工厂bean,则调用生成一个bean实例
if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
return beanInstance;
}
Object object = null;
//如果mdb(RootBeanDefinition)为null,直接从缓存中获取bean实例,spring会将生成好的单例bean缓存到currentHashMap中缓存起来
//这样,不用每次都去创建了
if (mbd == null) {
object = getCachedObjectForFactoryBean(beanName);
}
//走到这里,说明缓存没有命中,也就是说当前的bean是一个FactoryBean
if (object == null) {
// Return bean instance from factory.
FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
//查看此时的根据bean名称查看beanDefinitionMap中是否存在当前bean,beanDefinitionMap前面已经说过了,
//当spring加载完后,会将加载的bean全部放到beanDefinitionMap
if (mbd == null && containsBeanDefinition(beanName)) {
//合并BeanDefinition
mbd = getMergedLocalBeanDefinition(beanName);
}
//判断当前bean是否是合成的,synthetic合成的意思,但是这个地方没有具体理解这个用法到底是啥意思,后期在研究哈
boolean synthetic = (mbd != null && mbd.isSynthetic());
//从factoryBean中获取bean
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;
}
#FactoryBeanRegistrySupport
protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
//检查当前bean是否是单例
if (factory.isSingleton() && containsSingleton(beanName)) {
//缓存danlibean的map加锁
synchronized (getSingletonMutex()) {
//从缓存中获取bean
Object object = this.factoryBeanObjectCache.get(beanName);
if (object == null) {
//证明缓存在不存在,调用doGetObjectFromFactoryBean方法获取bean
object = doGetObjectFromFactoryBean(factory, beanName);
//这里再一次从缓存中获取一次bean,如果获取到了,将alreadyThere赋值给Object,源码解释说是解决循环引用的时候的操作
Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
if (alreadyThere != null) {
object = alreadyThere;
}
else {
//是否后置处理,
if (shouldPostProcess) {
if (isSingletonCurrentlyInCreation(beanName)) {
// Temporarily return non-post-processed object, not storing it yet..
return object;
}
beforeSingletonCreation(beanName);
try {
object = postProcessObjectFromFactoryBean(object, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName,
"Post-processing of FactoryBean's singleton object failed", ex);
}
finally {
afterSingletonCreation(beanName);
}
}
if (containsSingleton(beanName)) {
this.factoryBeanObjectCache.put(beanName, object);
}
}
}
return object;
}
}
else {
//走到这里,证明不是单例的,调用doGetObjectFromFactoryBean方法
Object object = doGetObjectFromFactoryBean(factory, beanName);
//判断是否需要进行后置处理
if (shouldPostProcess) {
try {
//从factoryBean发布处理对象
object = postProcessObjectFromFactoryBean(object, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);
}
}
return object;
}
}
private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName)
throws BeanCreationException {
Object object;
try {
//一些系统安全性检查.咱们就不看了
if (System.getSecurityManager() != null) {
AccessControlContext acc = getAccessControlContext();
try {
object = AccessController.doPrivileged((PrivilegedExceptionAction<Object>) factory::getObject, acc);
}
catch (PrivilegedActionException pae) {
throw pae.getException();
}
}
else {
//调用getObject方法返回bean对象
object = factory.getObject();
}
}
catch (FactoryBeanNotInitializedException ex) {
throw new BeanCurrentlyInCreationException(beanName, ex.toString());
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", ex);
}
if (object == null) {
//是否是当前正在创建的bean,如果是,直接抛出异常
if (isSingletonCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(
beanName, "FactoryBean which is currently in creation returned null from getObject");
}
//将object定义为null返回
object = new NullBean();
}
return object;
}
简单总结一下,代码比较多,但是逻辑不复杂,
1:判断是否是单例bean
2:从缓存在获取bean,
3:对bean执行后置处理
4:最后调用factory的getObject方法返回bean
好了,获取bean就简单分析到这里,代码比较简单,逻辑也不复杂,下一期,咱们再研究下创建单例bean的过程.Thanks!