Spring DI2--三级缓存获取Bean

Spring DI 源码分析一共有五篇
Spring DI1–整体流程
Spring DI2–三级缓存获取Bean
Spring DI3–从父级BeanFactory中获取Bean
Spring DI4–创建Bean
Spring DI5–不同作用域对Bean的处理

基于Spring 5.2.6.RELEASE

2、从缓存中获取单例bean

2.1、从缓存中获取单例bean

获取单例Bean,这里利用了三级缓存和一些标记,用来解决循环依赖

//DefaultSingletonBeanRegistry 类的属性
//一级缓存,存放初始化完成的Bean
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
//二级缓存,存放创建好但没有初始化完成的Bean,允许Bean提前暴露时有用
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);
//三级缓存,存放bean的创建工厂,按需会代理,单例Bean创建好后会移除
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
//正在创建的单例Bean
private final Set<String> singletonsCurrentlyInCreation = Collections.newSetFromMap(new ConcurrentHashMap<>(16));
//注册过的单例的beanName
private final Set<String> registeredSingletons = new LinkedHashSet<>(256);
//DefaultSingletonBeanRegistry#getSingleton(java.lang.String)
public Object getSingleton(String beanName) {
    //委派,允许提前暴露bean
	return getSingleton(beanName, true);
}
//org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(java.lang.String, boolean)
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
	//从一级缓存中获取单例bean
	Object singletonObject = this.singletonObjects.get(beanName);
	//以及缓存中没有,bean正在创建
	if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
		synchronized (this.singletonObjects) {//加锁
			//从二级缓存中获取未初始化好的单例bean
			singletonObject = this.earlySingletonObjects.get(beanName);
			//如果二级缓存中也没有,并且bean允许提前暴露
			if (singletonObject == null && allowEarlyReference) {
				//从三级缓存中获取ObjectFactory
				ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
				if (singletonFactory != null) {
					//获取Bean
					singletonObject = singletonFactory.getObject();
					//将新创建的bean放入二级缓存中
					this.earlySingletonObjects.put(beanName, singletonObject);
					//将三级缓存中的bean工厂移除
					this.singletonFactories.remove(beanName);
				}
			}
		}
	}
	//返回获取的bean
	return singletonObject;
}

判断当前bean是否正在创建

//org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#isSingletonCurrentlyInCreation
public boolean isSingletonCurrentlyInCreation(String beanName) {
	return this.singletonsCurrentlyInCreation.contains(beanName);
}

2.2、对获取到的bean进行factorybean处理

private final NamedThreadLocal<String> currentlyCreatedBean = new NamedThreadLocal<>("Currently created bean");
//org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#getObjectForBeanInstance
protected Object getObjectForBeanInstance(Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
	//获取当前线程正在创建的bean
    String currentlyCreatedBean = this.currentlyCreatedBean.get();
    if (currentlyCreatedBean != null) {
        registerDependentBean(beanName, currentlyCreatedBean);
    }

    return super.getObjectForBeanInstance(beanInstance, name, beanName, mbd);
}
2.2.1、注册依赖的bean到缓存
private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<>(64);
private final Map<String, Set<String>> dependenciesForBeanMap = new ConcurrentHashMap<>(64);
//org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#registerDependentBean
public void registerDependentBean(String beanName, String dependentBeanName) {
    //获取真正的beanName
    String canonicalName = canonicalName(beanName);
	//加锁
    synchronized (this.dependentBeanMap) {
        //如果没有设置过缓存,初始化当前beanName的缓存
        Set<String> dependentBeans =
            this.dependentBeanMap.computeIfAbsent(canonicalName, k -> new LinkedHashSet<>(8));
        //将当前依赖bean放入缓存
        if (!dependentBeans.add(dependentBeanName)) {
            return;
        }
    }

    synchronized (this.dependenciesForBeanMap) {
        //如果没有设置过缓存,初始化当前beanName的缓存
        Set<String> dependenciesForBean =
            this.dependenciesForBeanMap.computeIfAbsent(dependentBeanName, k -> new LinkedHashSet<>(8));
        //将当前依赖bean放入缓存
        dependenciesForBean.add(canonicalName);
    }
}
2.2.2、factorybean处理
//org.springframework.beans.factory.support.AbstractBeanFactory#getObjectForBeanInstance
protected Object getObjectForBeanInstance(Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {

    // Don't let calling code try to dereference the factory if the bean isn't a factory.
    //如果beanName以&开头,&是获取factorybean
    if (BeanFactoryUtils.isFactoryDereference(name)) {
        //为空,直接返回
        if (beanInstance instanceof NullBean) {
            return beanInstance;
        }
        //不是factorybean,抛异常
        if (!(beanInstance instanceof FactoryBean)) {
            throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
        }
        if (mbd != null) {
            mbd.isFactoryBean = true;
        }
        return beanInstance;
    }

    // Now we have the bean instance, which may be a normal bean or a FactoryBean.
    // If it's a FactoryBean, we use it to create a bean instance, unless the
    // caller actually wants a reference to the factory.
    //如果不是factorybean,返回
    if (!(beanInstance instanceof FactoryBean)) {
        return beanInstance;
    }

    Object object = null;
    if (mbd != null) {
        mbd.isFactoryBean = true;
    }
    else {
        //从缓存中获取bean
        object = getCachedObjectForFactoryBean(beanName);
    }
    //缓存中没有factorybean创建的单例bean,创建
    if (object == null) {
        // Return bean instance from factory.
        FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
        // Caches object obtained from FactoryBean if it is a singleton.
        //上面传入mbd是空
        if (mbd == null && containsBeanDefinition(beanName)) {
            mbd = getMergedLocalBeanDefinition(beanName);
        }
        boolean synthetic = (mbd != null && mbd.isSynthetic());
        object = getObjectFromFactoryBean(factory, beanName, !synthetic);
    }
    return object;
}
2.2.2.1、判断是否以&开头
//org.springframework.beans.factory.BeanFactoryUtils#isFactoryDereference
public static boolean isFactoryDereference(@Nullable String name) {
    return (name != null && name.startsWith(BeanFactory.FACTORY_BEAN_PREFIX));
}
2.2.2.2、从缓存中获取bean
//保存用factorybean创建的单例bean
private final Map<String, Object> factoryBeanObjectCache = new ConcurrentHashMap<>(16);
//org.springframework.beans.factory.support.FactoryBeanRegistrySupport#getCachedObjectForFactoryBean
protected Object getCachedObjectForFactoryBean(String beanName) {
    return this.factoryBeanObjectCache.get(beanName);
}

2.2.2.3、判断bean的beanDefinition是否存在
//这个就是ioc容器,存放bean的beanDefinition
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
//org.springframework.beans.factory.support.DefaultListableBeanFactory#containsBeanDefinition
public boolean containsBeanDefinition(String beanName) {
    Assert.notNull(beanName, "Bean name must not be null");
    return this.beanDefinitionMap.containsKey(beanName);
}

2.2.2.4、获取合并的BeanDefinition
private final Map<String, RootBeanDefinition> mergedBeanDefinitions = new ConcurrentHashMap<>(256);
//org.springframework.beans.factory.support.AbstractBeanFactory#getMergedLocalBeanDefinition
protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {
    // Quick check on the concurrent map first, with minimal locking.
    //如果合并的Beandefinition存在,则返回,否则合并BeanDefinition
    RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);
    if (mbd != null && !mbd.stale) {
        return mbd;
    }
    return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));
}

获取BeanDefinition

private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
//org.springframework.beans.factory.support.DefaultListableBeanFactory#getBeanDefinition
public BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException {
    BeanDefinition bd = this.beanDefinitionMap.get(beanName);
    if (bd == null) {
        if (logger.isTraceEnabled()) {
            logger.trace("No bean named '" + beanName + "' found in " + this);
        }
        throw new NoSuchBeanDefinitionException(beanName);
    }
    return bd;
}

获取合并的Beandefinition

//org.springframework.beans.factory.support.AbstractBeanFactory#getMergedBeanDefinition(java.lang.String, org.springframework.beans.factory.config.BeanDefinition)
protected RootBeanDefinition getMergedBeanDefinition(String beanName, BeanDefinition bd) throws BeanDefinitionStoreException {
    return getMergedBeanDefinition(beanName, bd, null);
}

合并所有层级的BeanDefinition

private final Map<String, RootBeanDefinition> mergedBeanDefinitions = new ConcurrentHashMap<>(256);
//org.springframework.beans.factory.support.AbstractBeanFactory#getMergedBeanDefinition(java.lang.String, org.springframework.beans.factory.config.BeanDefinition, org.springframework.beans.factory.config.BeanDefinition)
protected RootBeanDefinition getMergedBeanDefinition(String beanName, BeanDefinition bd, @Nullable BeanDefinition containingBd) throws BeanDefinitionStoreException {

    synchronized (this.mergedBeanDefinitions) {
        RootBeanDefinition mbd = null;
        RootBeanDefinition previous = null;

        // Check with full lock now in order to enforce the same merged instance.
        if (containingBd == null) {
            mbd = this.mergedBeanDefinitions.get(beanName);
        }

        if (mbd == null || mbd.stale) {
            previous = mbd;
            if (bd.getParentName() == null) {
                // Use copy of given root bean definition.
                if (bd instanceof RootBeanDefinition) {
                    mbd = ((RootBeanDefinition) bd).cloneBeanDefinition();
                }
                else {
                    mbd = new RootBeanDefinition(bd);
                }
            }
            else {
                // Child bean definition: needs to be merged with parent.
                BeanDefinition pbd;
                try {
                    String parentBeanName = transformedBeanName(bd.getParentName());
                    if (!beanName.equals(parentBeanName)) {
                        pbd = getMergedBeanDefinition(parentBeanName);
                    }
                    else {
                        BeanFactory parent = getParentBeanFactory();
                        if (parent instanceof ConfigurableBeanFactory) {
                            pbd = ((ConfigurableBeanFactory) parent).getMergedBeanDefinition(parentBeanName);
                        }
                        else {
                            throw new NoSuchBeanDefinitionException(parentBeanName,
                                                                    "Parent name '" + parentBeanName + "' is equal to bean name '" + beanName +
                                                                    "': cannot be resolved without a ConfigurableBeanFactory parent");
                        }
                    }
                }
                catch (NoSuchBeanDefinitionException ex) {
                    throw new BeanDefinitionStoreException(bd.getResourceDescription(), beanName,
                                                           "Could not resolve parent bean definition '" + bd.getParentName() + "'", ex);
                }
                // Deep copy with overridden values.
                mbd = new RootBeanDefinition(pbd);
                mbd.overrideFrom(bd);
            }

            // Set default singleton scope, if not configured before.
            if (!StringUtils.hasLength(mbd.getScope())) {
                mbd.setScope(SCOPE_SINGLETON);
            }

            // A bean contained in a non-singleton bean cannot be a singleton itself.
            // Let's correct this on the fly here, since this might be the result of
            // parent-child merging for the outer bean, in which case the original inner bean
            // definition will not have inherited the merged outer bean's singleton status.
            if (containingBd != null && !containingBd.isSingleton() && mbd.isSingleton()) {
                mbd.setScope(containingBd.getScope());
            }

            // Cache the merged bean definition for the time being
            // (it might still get re-merged later on in order to pick up metadata changes)
            if (containingBd == null && isCacheBeanMetadata()) {
                this.mergedBeanDefinitions.put(beanName, mbd);
            }
        }
        if (previous != null) {
            copyRelevantMergedBeanDefinitionCaches(previous, mbd);
        }
        return mbd;
    }
}

2.2.2.5、从FactoryBean获取bean
private final Map<String, Object> factoryBeanObjectCache = new ConcurrentHashMap<>(16);
//org.springframework.beans.factory.support.FactoryBeanRegistrySupport#getObjectFromFactoryBean
protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
    //单例 并且 缓存中有单例bean
    if (factory.isSingleton() && containsSingleton(beanName)) {
        synchronized (getSingletonMutex()) {
            //从缓存中获取单例FactoryBean创建的单例Bean
            Object object = this.factoryBeanObjectCache.get(beanName);
            //不存在已经创建好的单例bean
            if (object == null) {
                //用FactoryBean创建bean
                object = doGetObjectFromFactoryBean(factory, beanName);
                // Only post-process and store if not put there already during getObject() call above
                // (e.g. because of circular reference processing triggered by custom getBean calls)
                //如果缓存中存在了,直接取缓存中的bean,丢弃刚创建的bean,bean只会创建一次
                Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
                if (alreadyThere != null) {
                    object = alreadyThere;
                }
                else {//缓存中不存在
                    if (shouldPostProcess) {
                        //当前正在创建,返回不经过后置处理的bean
                        if (isSingletonCurrentlyInCreation(beanName)) {
                            // Temporarily return non-post-processed object, not storing it yet..
                            return object;
                        }
                        //检查是否未在创建bean
                        beforeSingletonCreation(beanName);
                        try {
                            //后置处理
                            object = postProcessObjectFromFactoryBean(object, beanName);
                        }
                        catch (Throwable ex) {
                            throw new BeanCreationException(beanName,
                                                            "Post-processing of FactoryBean's singleton object failed", ex);
                        }
                        finally {
                            //单例bean创建后检查
                            afterSingletonCreation(beanName);
                        }
                    }
                    //添加缓存
                    if (containsSingleton(beanName)) {
                        this.factoryBeanObjectCache.put(beanName, object);
                    }
                }
            }
            return object;
        }
    }
    else {
        Object object = doGetObjectFromFactoryBean(factory, beanName);
        if (shouldPostProcess) {
            try {
                object = postProcessObjectFromFactoryBean(object, beanName);
            }
            catch (Throwable ex) {
                throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);
            }
        }
        return object;
    }
}

2.2.2.5.1、判断缓存中是否存在factorybean
//org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#containsSingleton
public boolean containsSingleton(String beanName) {
    return this.singletonObjects.containsKey(beanName);
}

2.2.2.5.2、从factorybean中获取bean
//org.springframework.beans.factory.support.FactoryBeanRegistrySupport#doGetObjectFromFactoryBean
private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName) throws BeanCreationException {

    Object object;
    try {
        //如果需要java安全检查,安全检查后利用factorybean的getObject方法获取bean
        if (System.getSecurityManager() != null) {
            AccessControlContext acc = getAccessControlContext();
            try {
                object = AccessController.doPrivileged((PrivilegedExceptionAction<Object>) factory::getObject, acc);
            }
            catch (PrivilegedActionException pae) {
                throw pae.getException();
            }
        }
        else {//不需要安全检查,直接利用factorybean的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);
    }

    // Do not accept a null value for a FactoryBean that's not fully
    // initialized yet: Many FactoryBeans just return null then.
    if (object == null) {
        if (isSingletonCurrentlyInCreation(beanName)) {
            throw new BeanCurrentlyInCreationException(
                beanName, "FactoryBean which is currently in creation returned null from getObject");
        }
        object = new NullBean();
    }
    return object;
}

2.2.2.5.3、判断单例是否未在创建
private final Set<String> inCreationCheckExclusions = Collections.newSetFromMap(new ConcurrentHashMap<>(16));
//org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#beforeSingletonCreation
protected void beforeSingletonCreation(String beanName) {
    if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
        throw new BeanCurrentlyInCreationException(beanName);
    }
}

2.2.2.5.4、创建单例后的后置处理
//org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#postProcessObjectFromFactoryBean
protected Object postProcessObjectFromFactoryBean(Object object, String beanName) {
    return applyBeanPostProcessorsAfterInitialization(object, beanName);
}

factoryBean创建bean后,执行bean的后置处理器。

调用所有的后知处理器进行处理

//org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization
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

private final List<BeanPostProcessor> beanPostProcessors = new CopyOnWriteArrayList<>();
//org.springframework.beans.factory.support.AbstractBeanFactory#getBeanPostProcessors
public List<BeanPostProcessor> getBeanPostProcessors() {
    return this.beanPostProcessors;
}

2.2.2.5.5、单例创建后检查
//org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#afterSingletonCreation
protected void afterSingletonCreation(String beanName) {
    if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) {
        throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation");
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值