| Method from org.springframework.beans.factory.support.DefaultSingletonBeanRegistry Detail: |
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);
}
}
|
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);
}
}
}
Add the given singleton factory for building the specified singleton
if necessary.
To be called for eager registration of singletons, e.g. to be able to
resolve circular references. |
protected void afterSingletonCreation(String beanName) {
if (!this.singletonsCurrentlyInCreation.remove(beanName)) {
throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation");
}
}
|
protected void beforeSingletonCreation(String beanName) {
if (!this.singletonsCurrentlyInCreation.add(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
}
|
public boolean containsSingleton(String beanName) {
return (this.singletonObjects.containsKey(beanName));
}
|
protected void destroyBean(String beanName,
DisposableBean bean) {
Set dependencies = (Set) this.dependentBeanMap.remove(beanName);
if (dependencies != null) {
if (logger.isDebugEnabled()) {
logger.debug("Retrieved dependent beans for bean '" + beanName + "': " + dependencies);
}
for (Iterator it = dependencies.iterator(); it.hasNext();) {
String dependentBeanName = (String) it.next();
destroySingleton(dependentBeanName);
}
}
if (bean != null) {
try {
bean.destroy();
}
catch (Throwable ex) {
logger.error("Destroy method on bean with name '" + beanName + "' threw an exception", ex);
}
}
}
Destroy the given bean. Must destroy beans that depend on the given
bean before the bean itself. Should not throw any exceptions. |
public void destroySingleton(String beanName) {
// Remove a registered singleton of the given name, if any.
removeSingleton(beanName);
// Destroy the corresponding DisposableBean instance.
DisposableBean disposableBean = null;
synchronized (this.disposableBeans) {
disposableBean = (DisposableBean) this.disposableBeans.remove(beanName);
}
destroyBean(beanName, disposableBean);
}
Destroy the given bean. Delegates to destroyBean
if a corresponding disposable bean instance is found. |
public void destroySingletons() {
if (logger.isInfoEnabled()) {
logger.info("Destroying singletons in " + this);
}
synchronized (this.singletonObjects) {
this.singletonsCurrentlyInDestruction = true;
}
synchronized (this.disposableBeans) {
String[] disposableBeanNames = StringUtils.toStringArray(this.disposableBeans.keySet());
for (int i = disposableBeanNames.length - 1; i >= 0; i--) {
destroySingleton(disposableBeanNames[i]);
}
}
synchronized (this.singletonObjects) {
this.singletonObjects.clear();
this.singletonFactories.clear();
this.earlySingletonObjects.clear();
this.registeredSingletons.clear();
this.singletonsCurrentlyInDestruction = false;
}
}
|
public String[] getDependenciesForBean(String beanName) {
Set dependenciesForBean = (Set) this.dependenciesForBeanMap.get(beanName);
if (dependenciesForBean == null) {
return new String[0];
}
return (String[]) dependenciesForBean.toArray(new String[dependenciesForBean.size()]);
}
Return the names of all beans that the specified bean depends on, if any. |
public String[] getDependentBeans(String beanName) {
Set dependentBeans = (Set) this.dependentBeanMap.get(beanName);
if (dependentBeans == null) {
return new String[0];
}
return (String[]) dependentBeans.toArray(new String[dependentBeans.size()]);
}
Return the names of all beans which depend on the specified bean, if any. |
public Object getSingleton(String beanName) {
return getSingleton(beanName, true);
}
|
protected Object getSingleton(String beanName,
boolean allowEarlyReference) {
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
synchronized (this.singletonObjects) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
ObjectFactory singletonFactory = (ObjectFactory) 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.
Checks already instantiated singletons and also allows for an early
reference to a currently created singleton (resolving a circular reference). |
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 recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet();
}
try {
singletonObject = singletonFactory.getObject();
}
catch (BeanCreationException ex) {
if (recordSuppressedExceptions) {
for (Iterator it = this.suppressedExceptions.iterator(); it.hasNext();) {
ex.addRelatedCause((Exception) it.next());
}
}
throw ex;
}
finally {
if (recordSuppressedExceptions) {
this.suppressedExceptions = null;
}
afterSingletonCreation(beanName);
}
addSingleton(beanName, singletonObject);
}
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. |
public int getSingletonCount() {
synchronized (this.singletonObjects) {
return this.registeredSingletons.size();
}
}
|
protected final Object getSingletonMutex() {
return this.singletonObjects;
}
Expose the singleton mutex to subclasses.
Subclasses should synchronize on the given Object if they perform
any sort of extended singleton creation phase. In particular, subclasses
should not have their own mutexes involved in singleton creation,
to avoid the potential for deadlocks in lazy-init situations. |
public String[] getSingletonNames() {
synchronized (this.singletonObjects) {
return StringUtils.toStringArray(this.registeredSingletons);
}
}
|
protected boolean hasDependentBean(String beanName) {
return this.dependentBeanMap.containsKey(beanName);
}
Determine whether a dependent bean has been registered under the given name. |
public final boolean isSingletonCurrentlyInCreation(String beanName) {
return this.singletonsCurrentlyInCreation.contains(beanName);
}
Return whether the specified singleton bean is currently in creation
(within the entire factory). |
protected void onSuppressedException(Exception ex) {
synchronized (this.singletonObjects) {
if (this.suppressedExceptions != null) {
this.suppressedExceptions.add(ex);
}
}
}
Register an Exception that happened to get suppressed during the creation of a
singleton bean instance, e.g. a temporary circular reference resolution problem. |
public void registerDependentBean(String beanName,
String dependentBeanName) {
synchronized (this.dependentBeanMap) {
Set dependentBeans = (Set) this.dependentBeanMap.get(beanName);
if (dependentBeans == null) {
dependentBeans = new LinkedHashSet(8);
this.dependentBeanMap.put(beanName, dependentBeans);
}
dependentBeans.add(dependentBeanName);
}
synchronized (this.dependenciesForBeanMap) {
Set dependenciesForBean = (Set) this.dependenciesForBeanMap.get(dependentBeanName);
if (dependenciesForBean == null) {
dependenciesForBean = new LinkedHashSet(8);
this.dependenciesForBeanMap.put(dependentBeanName, dependenciesForBean);
}
dependenciesForBean.add(beanName);
}
}
Register a dependent bean for the given bean,
to be destroyed before the given bean is destroyed. |
public void registerDisposableBean(String beanName,
DisposableBean bean) {
synchronized (this.disposableBeans) {
this.disposableBeans.put(beanName, bean);
}
}
Add the given bean to the list of disposable beans in this registry.
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). |
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);
}
}
|
protected void removeSingleton(String beanName) {
synchronized (this.singletonObjects) {
this.singletonObjects.remove(beanName);
this.singletonFactories.remove(beanName);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.remove(beanName);
}
}
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. |