publicvoiddestroySingletons(){if(logger.isTraceEnabled()){ logger.trace("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(); clearSingletonCache();}
DefaultSingletonBeanRegistry#destroySingleton :
1
2
3
4
5
6
7
8
9
10
publicvoiddestroySingleton(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);}
protectedvoiddestroyBean(String beanName, @Nullable DisposableBean bean){// Trigger destruction of dependent beans first...
Set<String> dependencies;synchronized(this.dependentBeanMap){// Within full synchronization in order to guarantee a disconnected Set
dependencies =this.dependentBeanMap.remove(beanName);}if(dependencies !=null){if(logger.isTraceEnabled()){ logger.trace("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){if(logger.isWarnEnabled()){ logger.warn("Destruction of bean with name '"+ beanName +"' threw an exception", ex);}}}// Trigger destruction of contained beans...
Set<String> containedBeans;synchronized(this.containedBeanMap){// Within full synchronization in order to guarantee a disconnected Set
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);}