6.2-SingletonBeanRegistry-DefaultSingletonBeanRegistry
SingletonBeanRegistry
package org.springframework.beans.factory.config; public interface SingletonBeanRegistry { //在容器中创建一个指定的单利bean的类
void registerSingleton(String beanName, Object singletonObject); //返回一个单利类
Object getSingleton(String beanName); //判断容器红是否错在这个单例的bean
boolean containsSingleton(String beanName);
//返回这个单例bean的所有名字
String[] getSingletonNames(); //统计单例Bean的个数
int getSingletonCount(); Object getSingletonMutex(); }
DefaultSingletonBeanRegistry
/*
* Copyright 2002-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ package org.springframework.beans.factory.support; import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.BeanCreationException;
import org.springframework.beans.factory.BeanCreationNotAllowedException;
import org.springframework.beans.factory.BeanCurrentlyInCreationException;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.config.SingletonBeanRegistry;
import org.springframework.core.SimpleAliasRegistry;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils; /**
* Generic registry for shared bean instances, implementing the
* {@link org.springframework.beans.factory.config.SingletonBeanRegistry}.
* Allows for registering singleton instances that should be shared
* for all callers of the registry, to be obtained via bean name.
*
* <p>Also supports registration of
* {@link org.springframework.beans.factory.DisposableBean} instances,
* (which might or might not correspond to registered singletons),
* to be destroyed on shutdown of the registry. Dependencies between
* beans can be registered to enforce an appropriate shutdown order.
*
* <p>This class mainly serves as base class for
* {@link org.springframework.beans.factory.BeanFactory} implementations,
* factoring out the common management of singleton bean instances. Note that
* the {@link org.springframework.beans.factory.config.ConfigurableBeanFactory}
* interface extends the {@link SingletonBeanRegistry} interface.
*
* <p>Note that this class assumes neither a bean definition concept
* nor a specific creation process for bean instances, in contrast to
* {@link AbstractBeanFactory} and {@link DefaultListableBeanFactory}
* (which inherit from it). Can alternatively also be used as a nested
* helper to delegate to.
*
* @author Juergen Hoeller
* @since 2.0
* @see #registerSingleton
* @see #registerDisposableBean
* @see org.springframework.beans.factory.DisposableBean
* @see org.springframework.beans.factory.config.ConfigurableBeanFactory
*/
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry { /**
* Internal marker for a null singleton object:
* used as marker value for concurrent Maps (which don't support null values).
*/
protected static final Object NULL_OBJECT = new Object(); /** Logger available to subclasses */
protected final Log logger = LogFactory.getLog(getClass()); // 缓存了bean的名称和bean的实例
/** Cache of singleton objects: bean name --> bean instance */
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(256);
//缓存了bean的name 和 ObjectFactory
/** Cache of singleton factories: bean name --> ObjectFactory */
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<String, ObjectFactory<?>>(16);
//缓存了已经存在单例,用于解决循环依赖的方法
/** Cache of early singleton objects: bean name --> bean instance */
private final Map<String, Object> earlySingletonObjects = new HashMap<String, Object>(16);
//已经注册好的单例
/** Set of registered singletons, containing the bean names in registration order */
private final Set<String> registeredSingletons = new LinkedHashSet<String>(256);
// 存正在初始化的bean。就不在发起初始化
/** Names of beans that are currently in creation */
private final Set<String> singletonsCurrentlyInCreation =
Collections.newSetFromMap(new ConcurrentHashMap<String, Boolean>(16));
// 直接缓存当前不能加载的bean
/** Names of beans currently excluded from in creation checks */
private final Set<String> inCreationCheckExclusions =
Collections.newSetFromMap(new ConcurrentHashMap<String, Boolean>(16)); /** List of suppressed Exceptions, available for associating related causes */
private Set<Exception> suppressedExceptions; /** Flag that indicates whether we're currently within destroySingletons */
private boolean singletonsCurrentlyInDestruction = false;
//
/** Disposable bean instances: bean name --> disposable instance */
private final Map<String, Object> disposableBeans = new LinkedHashMap<String, Object>(); /** Map between containing bean names: bean name --> Set of bean names that the bean contains */
private final Map<String, Set<String>> containedBeanMap = new ConcurrentHashMap<String, Set<String>>(16);
//查找依赖的类
/** Map between dependent bean names: bean name --> Set of dependent bean names */
private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<String, Set<String>>(64);
//被依赖的bean name为key
/** Map between depending bean names: bean name --> Set of bean names for the bean's dependencies */
private final Map<String, Set<String>> dependenciesForBeanMap = new ConcurrentHashMap<String, Set<String>>(64); //注册单例bean
@Override
public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException {
Assert.notNull(beanName, "'beanName' must not be null");
synchronized (this.singletonObjects) {
Object oldObject = this.singletonObjects.get(beanName);
if (oldObject != null) {
throw new IllegalStateException("Could not register object [" + singletonObject +
"] under bean name '" + beanName + "': there is already object [" + oldObject + "] bound");
}
addSingleton(beanName, singletonObject);
}
} /**
* Add the given singleton object to the singleton cache of this factory.
* <p>To be called for eager registration of singletons.
* @param beanName the name of the bean
* @param singletonObject the singleton object
*/
protected void addSingleton(String beanName, Object singletonObject) {
synchronized (this.singletonObjects) {
this.singletonObjects.put(beanName, (singletonObject != null ? singletonObject : NULL_OBJECT));
this.singletonFactories.remove(beanName);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
} /**
* Add the given singleton factory for building the specified singleton
* if necessary.
* <p>To be called for eager registration of singletons, e.g. to be able to
* resolve circular references.
* @param beanName the name of the bean
* @param singletonFactory the factory for the singleton object
*/
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(singletonFactory, "Singleton factory must not be null");
synchronized (this.singletonObjects) {
if (!this.singletonObjects.containsKey(beanName)) {
this.singletonFactories.put(beanName, singletonFactory);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
} @Override
public Object getSingleton(String beanName) {
return getSingleton(beanName, true);
} /**
* Return the (raw) singleton object registered under the given name.
* <p>Checks already instantiated singletons and also allows for an early
* reference to a currently created singleton (resolving a circular reference).
* @param beanName the name of the bean to look for
* @param allowEarlyReference whether early references should be created or not
* @return the registered singleton object, or {@code null} if none found
*/
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 != NULL_OBJECT ? singletonObject : null);
} /**
* Return the (raw) singleton object registered under the given name,
* creating and registering a new one if none registered yet.
* @param beanName the name of the bean
* @param singletonFactory the ObjectFactory to lazily create the singleton
* with, if necessary
* @return the registered singleton object
*/
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(beanName, "'beanName' 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 the 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<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;
}
afterSingletonCreation(beanName);
}
if (newSingleton) {
addSingleton(beanName, singletonObject);
}
}
return (singletonObject != NULL_OBJECT ? singletonObject : null);
}
} /**
* Register an Exception that happened to get suppressed during the creation of a
* singleton bean instance, e.g. a temporary circular reference resolution problem.
* @param ex the Exception to register
*/
protected void onSuppressedException(Exception ex) {
synchronized (this.singletonObjects) {
if (this.suppressedExceptions != null) {
this.suppressedExceptions.add(ex);
}
}
} /**
* Remove the bean with the given name from the singleton cache of this factory,
* to be able to clean up eager registration of a singleton if creation failed.
* @param beanName the name of the bean
* @see #getSingletonMutex()
*/
protected void removeSingleton(String beanName) {
synchronized (this.singletonObjects) {
this.singletonObjects.remove(beanName);
this.singletonFactories.remove(beanName);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.remove(beanName);
}
} @Override
public boolean containsSingleton(String beanName) {
return this.singletonObjects.containsKey(beanName);
} @Override
public String[] getSingletonNames() {
synchronized (this.singletonObjects) {
return StringUtils.toStringArray(this.registeredSingletons);
}
} @Override
public int getSingletonCount() {
synchronized (this.singletonObjects) {
return this.registeredSingletons.size();
}
} public void setCurrentlyInCreation(String beanName, boolean inCreation) {
Assert.notNull(beanName, "Bean name must not be null");
if (!inCreation) {
this.inCreationCheckExclusions.add(beanName);
}
else {
this.inCreationCheckExclusions.remove(beanName);
}
} public boolean isCurrentlyInCreation(String beanName) {
Assert.notNull(beanName, "Bean name must not be null");
return (!this.inCreationCheckExclusions.contains(beanName) && isActuallyInCreation(beanName));
} protected boolean isActuallyInCreation(String beanName) {
return isSingletonCurrentlyInCreation(beanName);
} /**
* Return whether the specified singleton bean is currently in creation
* (within the entire factory).
* @param beanName the name of the bean
*/
public boolean isSingletonCurrentlyInCreation(String beanName) {
return this.singletonsCurrentlyInCreation.contains(beanName);
} /**
* Callback before singleton creation.
* <p>The default implementation register the singleton as currently in creation.
* @param beanName the name of the singleton about to be created
* @see #isSingletonCurrentlyInCreation
*/
protected void beforeSingletonCreation(String beanName) {
if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
} /**
* Callback after singleton creation.
* <p>The default implementation marks the singleton as not in creation anymore.
* @param beanName the name of the singleton that has been created
* @see #isSingletonCurrentlyInCreation
*/
protected void afterSingletonCreation(String beanName) {
if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) {
throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation");
}
} /**
* Add the given bean to the list of disposable beans in this registry.
* <p>Disposable beans usually correspond to registered singletons,
* matching the bean name but potentially being a different instance
* (for example, a DisposableBean adapter for a singleton that does not
* naturally implement Spring's DisposableBean interface).
* @param beanName the name of the bean
* @param bean the bean instance
*/
public void registerDisposableBean(String beanName, DisposableBean bean) {
synchronized (this.disposableBeans) {
this.disposableBeans.put(beanName, bean);
}
} /**
* Register a containment relationship between two beans,
* e.g. between an inner bean and its containing outer bean.
* <p>Also registers the containing bean as dependent on the contained bean
* in terms of destruction order.
* @param containedBeanName the name of the contained (inner) bean
* @param containingBeanName the name of the containing (outer) bean
* @see #registerDependentBean
*/
public void registerContainedBean(String containedBeanName, String containingBeanName) {
// A quick check for an existing entry upfront, avoiding synchronization...
Set<String> containedBeans = this.containedBeanMap.get(containingBeanName);
if (containedBeans != null && containedBeans.contains(containedBeanName)) {
return;
} // No entry yet -> fully synchronized manipulation of the containedBeans Set
synchronized (this.containedBeanMap) {
containedBeans = this.containedBeanMap.get(containingBeanName);
if (containedBeans == null) {
containedBeans = new LinkedHashSet<String>(8);
this.containedBeanMap.put(containingBeanName, containedBeans);
}
containedBeans.add(containedBeanName);
}
registerDependentBean(containedBeanName, containingBeanName);
} /**
* Register a dependent bean for the given bean,
* to be destroyed before the given bean is destroyed.
* @param beanName the name of the bean
* @param dependentBeanName the name of the dependent bean
*/
public void registerDependentBean(String beanName, String dependentBeanName) {
// A quick check for an existing entry upfront, avoiding synchronization...
String canonicalName = canonicalName(beanName);
Set<String> dependentBeans = this.dependentBeanMap.get(canonicalName);
if (dependentBeans != null && dependentBeans.contains(dependentBeanName)) {
return;
} // No entry yet -> fully synchronized manipulation of the dependentBeans Set
synchronized (this.dependentBeanMap) {
dependentBeans = this.dependentBeanMap.get(canonicalName);
if (dependentBeans == null) {
dependentBeans = new LinkedHashSet<String>(8);
this.dependentBeanMap.put(canonicalName, dependentBeans);
}
dependentBeans.add(dependentBeanName);
}
synchronized (this.dependenciesForBeanMap) {
Set<String> dependenciesForBean = this.dependenciesForBeanMap.get(dependentBeanName);
if (dependenciesForBean == null) {
dependenciesForBean = new LinkedHashSet<String>(8);
this.dependenciesForBeanMap.put(dependentBeanName, dependenciesForBean);
}
dependenciesForBean.add(canonicalName);
}
} /**
* Determine whether the specified dependent bean has been registered as
* dependent on the given bean or on any of its transitive dependencies.
* @param beanName the name of the bean to check
* @param dependentBeanName the name of the dependent bean
* @since 4.0
*/
protected boolean isDependent(String beanName, String dependentBeanName) {
return isDependent(beanName, dependentBeanName, null);
} private boolean isDependent(String beanName, String dependentBeanName, Set<String> alreadySeen) {
if (alreadySeen != null && alreadySeen.contains(beanName)) {
return false;
}
String canonicalName = canonicalName(beanName);
Set<String> dependentBeans = this.dependentBeanMap.get(canonicalName);
if (dependentBeans == null) {
return false;
}
if (dependentBeans.contains(dependentBeanName)) {
return true;
}
for (String transitiveDependency : dependentBeans) {
if (alreadySeen == null) {
alreadySeen = new HashSet<String>();
}
alreadySeen.add(beanName);
if (isDependent(transitiveDependency, dependentBeanName, alreadySeen)) {
return true;
}
}
return false;
} /**
* Determine whether a dependent bean has been registered for the given name.
* @param beanName the name of the bean to check
*/
protected boolean hasDependentBean(String beanName) {
return this.dependentBeanMap.containsKey(beanName);
} /**
* Return the names of all beans which depend on the specified bean, if any.
* @param beanName the name of the bean
* @return the array of dependent bean names, or an empty array if none
*/
public String[] getDependentBeans(String beanName) {
Set<String> dependentBeans = this.dependentBeanMap.get(beanName);
if (dependentBeans == null) {
return new String[0];
}
return StringUtils.toStringArray(dependentBeans);
} /**
* Return the names of all beans that the specified bean depends on, if any.
* @param beanName the name of the bean
* @return the array of names of beans which the bean depends on,
* or an empty array if none
*/
public String[] getDependenciesForBean(String beanName) {
Set<String> dependenciesForBean = this.dependenciesForBeanMap.get(beanName);
if (dependenciesForBean == null) {
return new String[0];
}
return dependenciesForBean.toArray(new String[dependenciesForBean.size()]);
} public void destroySingletons() {
if (logger.isDebugEnabled()) {
logger.debug("Destroying singletons in " + this);
}
synchronized (this.singletonObjects) {
this.singletonsCurrentlyInDestruction = true;
} String[] disposableBeanNames;
synchronized (this.disposableBeans) {
disposableBeanNames = StringUtils.toStringArray(this.disposableBeans.keySet());
}
for (int i = disposableBeanNames.length - 1; i >= 0; i--) {
destroySingleton(disposableBeanNames[i]);
} this.containedBeanMap.clear();
this.dependentBeanMap.clear();
this.dependenciesForBeanMap.clear(); synchronized (this.singletonObjects) {
this.singletonObjects.clear();
this.singletonFactories.clear();
this.earlySingletonObjects.clear();
this.registeredSingletons.clear();
this.singletonsCurrentlyInDestruction = false;
}
} /**
* Destroy the given bean. Delegates to {@code destroyBean}
* if a corresponding disposable bean instance is found.
* @param beanName the name of the bean
* @see #destroyBean
*/
public void destroySingleton(String beanName) {
// Remove a registered singleton of the given name, if any.
removeSingleton(beanName); // Destroy the corresponding DisposableBean instance.
DisposableBean disposableBean;
synchronized (this.disposableBeans) {
disposableBean = (DisposableBean) this.disposableBeans.remove(beanName);
}
destroyBean(beanName, disposableBean);
} /**
* Destroy the given bean. Must destroy beans that depend on the given
* bean before the bean itself. Should not throw any exceptions.
* @param beanName the name of the bean
* @param bean the bean instance to destroy
*/
protected void destroyBean(String beanName, DisposableBean bean) {
// Trigger destruction of dependent beans first...
Set<String> dependencies = this.dependentBeanMap.remove(beanName);
if (dependencies != null) {
if (logger.isDebugEnabled()) {
logger.debug("Retrieved dependent beans for bean '" + beanName + "': " + dependencies);
}
for (String dependentBeanName : dependencies) {
destroySingleton(dependentBeanName);
}
} // Actually destroy the bean now...
if (bean != null) {
try {
bean.destroy();
}
catch (Throwable ex) {
logger.error("Destroy method on bean with name '" + beanName + "' threw an exception", ex);
}
} // Trigger destruction of contained beans...
Set<String> containedBeans = this.containedBeanMap.remove(beanName);
if (containedBeans != null) {
for (String containedBeanName : containedBeans) {
destroySingleton(containedBeanName);
}
} // Remove destroyed bean from other beans' dependencies.
synchronized (this.dependentBeanMap) {
for (Iterator<Map.Entry<String, Set<String>>> it = this.dependentBeanMap.entrySet().iterator(); it.hasNext();) {
Map.Entry<String, Set<String>> entry = it.next();
Set<String> dependenciesToClean = entry.getValue();
dependenciesToClean.remove(beanName);
if (dependenciesToClean.isEmpty()) {
it.remove();
}
}
} // Remove destroyed bean's prepared dependency information.
this.dependenciesForBeanMap.remove(beanName);
} /**
* Exposes the singleton mutex to subclasses and external collaborators.
* <p>Subclasses should synchronize on the given Object if they perform
* any sort of extended singleton creation phase. In particular, subclasses
* should <i>not</i> have their own mutexes involved in singleton creation,
* to avoid the potential for deadlocks in lazy-init situations.
*/
public final Object getSingletonMutex() {
return this.singletonObjects;
} }
注册bean的这段代码:
@Override
public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException {
Assert.notNull(beanName, "'beanName' must not be null");
synchronized (this.singletonObjects) {
Object oldObject = this.singletonObjects.get(beanName);
if (oldObject != null) {
throw new IllegalStateException("Could not register object [" + singletonObject +
"] under bean name '" + beanName + "': there is already object [" + oldObject + "] bound");
}
addSingleton(beanName, singletonObject);
}
}
同样使用了同步方法来维护线程的安全, 调用了
addSingleton(beanName, singletonObject);
protected void addSingleton(String beanName, Object singletonObject) {
synchronized (this.singletonObjects) {
this.singletonObjects.put(beanName, (singletonObject != null ? singletonObject : NULL_OBJECT));
this.singletonFactories.remove(beanName);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
上述的方法中我们可以看出,存储bean的几个集合的关系了,
singletonObjects,
registeredSingletons是同步的,和
singletonFactories
earlySingletonObjects是相互对立的关系,不会同时存在
管理bean的依赖问题
使用如下三个属性进行管理:
Map<String, Set<String>> containedBeanMap 依赖的bean name为key , 就是依赖类 -> 查找 被依赖的类
Map<String, Set<String>> dependentBeanMap 依赖的原始bean name为key
Map<String, Set<String>> dependenciesForBeanMap 被依赖的bean name为key
在进行public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) 时候,先进行了
beforeSingletonCreation这边inCreationCheckExclusions不包含beanName才会去判断singletonsCurrentlyInCreation
protected void beforeSingletonCreation(String beanName) {
if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
}
销毁:最后还有一个public void destroySingleton(String beanName)的方法,
其实源码中就是把之前存在集合中得Bean进行了移除!就相当于是销毁了。 解释不合理的地方,请指正!谢谢了!
6.2-SingletonBeanRegistry-DefaultSingletonBeanRegistry的更多相关文章
- Spring之25:SingletonBeanRegistry&DefaultSingletonBeanRegistry
此接口是针对Spring中的单例Bean设计的.提供了统一访问单例Bean的功能,BeanFactory可实现此接口以提供访问内部单例Bean的能力. //将对象(singletonObject)注册 ...
- Spring IoC容器与应用上下文的设计与实现
一.前言 写这篇博文的主要目的如下: 通过相关类和接口分析IoC容器到底长什么样. 阐述笔者对Spring上下文和容器的理解. 介绍重要的类辅助理解SpringBoot的启动流程. 二.Spring ...
- 从Spring中学到的【1】--读懂继承链
最近看了一些 Spring 源码,发现源码分析的文章很多,而底层思想分析的文章比较少,这个系列文章准备总结一下Spring中给我的启示,包括设计模式思想.SOLID设计原则等,涉及一些编程的基本原则, ...
- DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry
// 用于内部标记的空的单例对象(不支持null)protected static final Object NULL_OBJECT = new Object(); // 缓存单例对象根据beanNa ...
- DefaultSingletonBeanRegistry
DefaultSingletonBeanRegistry 这是 DefaultSingletonBeanRegistry 类的体系结构,由一个类一个责任的原则: AliasRegistry : 提供别 ...
- 哈哈,原来IOC容器的bean是存在DefaultSingletonBeanRegistry的一个Map类型的属性当中。
经过查看源代码发现IOC容器中的bean实例(不知道是不是所有的bean)是存储在一个DefaultSingletonBeanRegistry类实例的一个Map类型的属性当中. 下面是DefaultS ...
- 单例Bean注册表接口SingletonBeanRegistry
Github: SingletonBeanRegistry.java SingletonBeanRegistry package org.springframework.beans.factory.c ...
- Spring(六)核心容器 - 注册单例 Bean 实例、SingletonBeanRegistry 简介
前言 上篇文章我们对注册 Bean 的核心类 BeanDefinitionRegistry 进行了讨论,这里的注册 Bean 是指保存 Bean 的相关信息,也就是将 Bean 定义成 BeanDef ...
- DefaultSingletonBeanRegistry源码解析
DefaultSingletonBeanRegistry是SingletionBean注册器的默认实现. 来学习下DefaultSingletonBeanRegistry的源码: package or ...
- 一则spring容器启动死锁问题(DefaultListableBeanFactory/DefaultSingletonBeanRegistry)
线上发现一个问题,应用在启动时会卡死,log上并没有什么异常输出,初判应该是死锁问题. 抓现场的thread dump文件, 确实是有两个线程有deadlock问题. 线程一 "HSFBiz ...
随机推荐
- 【温故知新】—— React/Redux/React-router4基础知识&独立团Demo
前言:React专注View层,一切皆组件:全部使用ES6语法,最新版本为React16. Redux是专注于状态管理的库,和react解耦:单一状态,单向数据流.[独立团github地址] 一.Re ...
- ECShop后台管理菜单修改
ECShop中,和后台菜单相关的文件有两个: ·菜单项:admin\includes\inc_menu.php·菜单文本:languages\zh_cn\admin\common.php 所以,要修改 ...
- 【ecshop---新增包邮卡功能】
一:需求分析 项目组要求新增类似虚拟卡的包邮卡,用户获得包邮卡的方式包括后台发送和前台自助充值.包邮卡有使用期限.订单使用包邮卡免除邮费.可以和其他优惠活动同时进行! 二:开发功能点 后台:新增包邮卡 ...
- [阿里Hao]Android无线开发的几种经常使用技术
本文由阿里巴巴移动安全client.YunOS资深project师Hao(嵌入式企鹅圈原创团队成员)撰写,是Hao在嵌入式企鹅圈发表的第一篇原创文章.对Android无线开发的几种经常使用技术进行综述 ...
- FizzBuzz and Fibonacci优化
***************************************转载请注明出处:http://blog.csdn.net/lttree************************** ...
- ListView:聊天界面
一.最终成型图 二.主界面xml布局 <?xml version="1.0" encoding="utf-8"?> <LinearLayout ...
- 正则表达式---A bytes of python
正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符.及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑. 给定一个正则表达式和另一个 ...
- Step 2---有关Github的几个问题
1.取得项目的Git仓库的方式 第一种是在现存的目录下,通过导入所有文件来创建新的 Git 仓库. 要对现有的某个项目开始用 Git 管理,只需到此项目所在的目录,执行: $ git init 初始化 ...
- CentOS6.8 搭建SVN并用钩子自动实现同步到web目录
一 安装 yum install subversion 二 检查是否安装成功 svn --version 三 创建仓库目录 mkdir –p /home/svnroot/test 四 创建项目 svn ...
- 类中的internal成员可能是一种坏味道
前言 最近除了搞ASP.NET MVC之外,我也在思考一些编程实践方面的问题.昨天在回家路上,我忽然对一个问题产生了较为清晰的认识.或者说,原先只是有一丝细微的感觉,而现在将它和一些其他的方面进行了联 ...