一:DefaultSingletonBeanRegistry之destroySingleton(String beanName)
销毁单例bean
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);
}
方法简析:
- 1.将缓存的单例bean移除出map
- 2.移除disposableBeans中缓存的DisposableBean对象
- 3.销毁bean以及依赖于这个单例bean的bean对象,还有单例bean中包含的其他bean
移除缓存的单例bean之removeSingleton(beanName)
protected void removeSingleton(String beanName) {
synchronized (this.singletonObjects) {
this.singletonObjects.remove(beanName);
this.singletonFactories.remove(beanName);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.remove(beanName);
}
}
方法简析:
- 1.锁定单例对象缓存map,防止其他线程影响销毁过程
- 2.从单例对象缓存map中移除bean
- 3.从单例对象创建工厂map中移除ObjectFactory
- 4.从earlySingletonObjects中移除bean
- 5.移除已注册的单例bean的beanName
销毁bean之destroyBean(String beanName, DisposableBean bean)
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);
}
方法简析:
- 1.率先销毁所有依赖于这个单例bean的所有bean,道理很简单,如果当前单例bean被销毁了,而依赖于当前单例bean的bean对象调用单例bean时必然会出现空指针异常
- 2.真正开始执行单例bean的destroy()方法来销毁bean
- 3.containedBeanMap销毁这个单例bean中包含的其他bean对象(即引入的依赖,但是实际上这个map好像并没有用到,而且引用的bean也不应该立即销毁,因为可能有其他bean同时也在引用,或许应该检查到没有引用的时候再销毁,但是spring中好像并没有这么做)
- 4.从依赖bean缓存列表dependentBeanMap中(键值对,如service->controller list)删除所有相关被依赖项
- 5.删除依赖列表dependenciesForBeanMap(键值对,如controller -> service list)
二:DisposableBeanAdapter
上面讲到从disposableBeans列表中移除DisposableBean对象,现在来看一下spring是如何注册DisposableBean对象的:
public void registerDisposableBean(String beanName, DisposableBean bean) {
synchronized (this.disposableBeans) {
this.disposableBeans.put(beanName, bean);
}
}
//AbstractBeanFactory.registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd)
protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null);
if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {
if (mbd.isSingleton()) {
// Register a DisposableBean implementation that performs all destruction
// work for the given bean: DestructionAwareBeanPostProcessors,
// DisposableBean interface, custom destroy method.
registerDisposableBean(beanName,
new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
}
else {
// A bean with a custom scope...
Scope scope = this.scopes.get(mbd.getScope());
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + mbd.getScope() + "'");
}
scope.registerDestructionCallback(beanName,
new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
}
}
}
//检查是否需要销毁
//AbstractBeanFactory.requiresDestruction(Object bean, RootBeanDefinition mbd)
protected boolean requiresDestruction(Object bean, RootBeanDefinition mbd) {
return (bean != null &&
(DisposableBeanAdapter.hasDestroyMethod(bean, mbd) || (hasDestructionAwareBeanPostProcessors() &&
DisposableBeanAdapter.hasApplicableProcessors(bean, getBeanPostProcessors()))));
}
方法简析:
- 1.检查当前bean的作用域以及是否需要销毁(比如BeanDefinition是否定义了销毁方法,或者注册了针对该bean的DestructionAwareBeanPostProcessor),多例将不会注册DisposableBean对象
- 2.如果是单例,则注册DisposableBeanAdapter对象
- 3.如果不是单例,则有可能是request、session、globalSession、refresh或者其他自定义的scope,这时将会注册异步的销毁对象
DisposableBeanAdapter中重要方法简析
1.构造方法
public DisposableBeanAdapter(Object bean, String beanName, RootBeanDefinition beanDefinition,
List<BeanPostProcessor> postProcessors, AccessControlContext acc) {
Assert.notNull(bean, "Disposable bean must not be null");
this.bean = bean;
this.beanName = beanName;
this.invokeDisposableBean =
(this.bean instanceof DisposableBean && !beanDefinition.isExternallyManagedDestroyMethod("destroy"));
this.nonPublicAccessAllowed = beanDefinition.isNonPublicAccessAllowed();
this.acc = acc;
String destroyMethodName = inferDestroyMethodIfNecessary(bean, beanDefinition);
if (destroyMethodName != null && !(this.invokeDisposableBean && "destroy".equals(destroyMethodName)) &&
!beanDefinition.isExternallyManagedDestroyMethod(destroyMethodName)) {
this.destroyMethodName = destroyMethodName;
this.destroyMethod = determineDestroyMethod();
if (this.destroyMethod == null) {
if (beanDefinition.isEnforceDestroyMethod()) {
throw new BeanDefinitionValidationException("Couldn't find a destroy method named '" +
destroyMethodName + "' on bean with name '" + beanName + "'");
}
}
else {
Class<?>[] paramTypes = this.destroyMethod.getParameterTypes();
if (paramTypes.length > 1) {
throw new BeanDefinitionValidationException("Method '" + destroyMethodName + "' of bean '" +
beanName + "' has more than one parameter - not supported as destroy method");
}
else if (paramTypes.length == 1 && boolean.class != paramTypes[0]) {
throw new BeanDefinitionValidationException("Method '" + destroyMethodName + "' of bean '" +
beanName + "' has a non-boolean parameter - not supported as destroy method");
}
}
}
this.beanPostProcessors = filterPostProcessors(postProcessors, bean);
}
方法简析:
- 1.检查是否实现了DisposableBean接口
- 2.寻找销毁方法名destroyMethodName
- 3.如果找到了销毁方法,并且bean没有实现DisposableBean接口或者设置了除destroy()之外的方法,以及非外部管理的销毁方法,则会根据destroyMethodName寻找销毁方法(这里需要注意,销毁方法参数不能超过1个,且只能是boolean类型的)
- 4.在BeanPostProcessor列表中查找实现DestructionAwareBeanPostProcessor接口的实例并且决定当前bean是需要被销毁的,然后将其放入beanPostProcessors列表中
2.寻找销毁方法
private String inferDestroyMethodIfNecessary(Object bean, RootBeanDefinition beanDefinition) {
String destroyMethodName = beanDefinition.getDestroyMethodName();
if (AbstractBeanDefinition.INFER_METHOD.equals(destroyMethodName) ||
(destroyMethodName == null && closeableInterface.isInstance(bean))) {
// Only perform destroy method inference or Closeable detection
// in case of the bean not explicitly implementing DisposableBean
if (!(bean instanceof DisposableBean)) {
try {
return bean.getClass().getMethod(CLOSE_METHOD_NAME).getName();
}
catch (NoSuchMethodException ex) {
try {
return bean.getClass().getMethod(SHUTDOWN_METHOD_NAME).getName();
}
catch (NoSuchMethodException ex2) {
// no candidate destroy method found
}
}
}
return null;
}
return (StringUtils.hasLength(destroyMethodName) ? destroyMethodName : null);
}
方法简析:
- 1.从BeanDefinition中拿到destroyMethodName
- 2.判断是否是默认值-"(inferred)",或者destroyMethodName为null并且bean是AutoCloseable或Closeable的实现类
- 3.如果满足上述条件,判断是否是DisposableBean的实现类,如果是则不做推断,如果不是,则尝试获取名"close"或"shutdown"的方法
- 4.如果不满足条件并且destroyMethodName不为空,则直接返回destroyMethodName
3.bean的销毁行为之destroy()
public void destroy() {
if (!CollectionUtils.isEmpty(this.beanPostProcessors)) {
for (DestructionAwareBeanPostProcessor processor : this.beanPostProcessors) {
processor.postProcessBeforeDestruction(this.bean, this.beanName);
}
}
if (this.invokeDisposableBean) {
if (logger.isDebugEnabled()) {
logger.debug("Invoking destroy() on bean with name '" + this.beanName + "'");
}
try {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
@Override
public Object run() throws Exception {
((DisposableBean) bean).destroy();
return null;
}
}, acc);
}
else {
((DisposableBean) bean).destroy();
}
}
catch (Throwable ex) {
String msg = "Invocation of destroy method failed on bean with name '" + this.beanName + "'";
if (logger.isDebugEnabled()) {
logger.warn(msg, ex);
}
else {
logger.warn(msg + ": " + ex);
}
}
}
if (this.destroyMethod != null) {
invokeCustomDestroyMethod(this.destroyMethod);
}
else if (this.destroyMethodName != null) {
Method methodToCall = determineDestroyMethod();
if (methodToCall != null) {
invokeCustomDestroyMethod(methodToCall);
}
}
}
方法简析:
- 1.从bean销毁处理器列表beanPostProcessors获取到DestructionAwareBeanPostProcessor实例并执行postProcessBeforeDestruction(Object bean, String beanName)方法进行bean销毁之前的行为
- 2.如果bean实现了DisposableBean接口,则执行其实现的destroy()行为
- 3.通过反射执行自定义或推断而出的destroyMethod