spring bean 销毁的 N 种方式
嘻嘻 /ᐠ。ꞈ。ᐟ\
博主开篇打个广告哈~
博主在 哔哩哔哩 有陆续录制了一些教学视频,有兴趣的小伙伴可以去瞅瞅,求三连~
UP主 肖-信 https://space.bilibili.com/384638478
正文
常用方式
@PreDestroy
@PreDestroy
private void preDestory() {
System.out.println("销毁啦!!德玛西亚");
}
实现 DisposableBean接口
实现 DisposableBean接口 重写 destroy方法
@Service
public class XianJian implements DisposableBean {
@PreDestroy
private void preDestory() {
System.out.println("销毁啦!!德玛西亚 preDestory");
}
@Override
public void destroy() throws Exception {
System.out.println("销毁啦!!德玛西亚 destroy");
}
}
另辟蹊径
destroyMethod
定义 Bean 指定 destoryMethod
@Bean(destroyMethod = "beanDestroyMethod")
public XianJian xianJian() {
return new XianJian();
}
public class XianJian implements DisposableBean {
@PreDestroy
private void preDestory() {
System.out.println("销毁啦!!德玛西亚 preDestory");
}
@Override
public void destroy() throws Exception {
System.out.println("销毁啦!!德玛西亚 destroy");
}
public void beanDestroyMethod(){
System.out.println("销毁啦!!德玛西亚 beanDestroyMethod");
}
}
AutoCloseable
实现 AutoCloseable 接口 重写 close接口
@Component
public class XianJian implements AutoCloseable{
public void close() {
System.out.println("销毁啦!!德玛西亚 close ");
}
}
修改BeanDifinition
这种方式用的最少…
将 beanDefinition 的 destroyMethodName 设置为 (inferred)
@Component
public class XxxProcessor implements MergedBeanDefinitionPostProcessor {
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
if(beanName.equals("xianJian")){
beanDefinition.setDestroyMethodName("(inferred)");
}
}
@Override
public void resetBeanDefinition(String beanName) {
MergedBeanDefinitionPostProcessor.super.resetBeanDefinition(beanName);
}
}
然后编写 close 或者 shutdown 方法,若都编写则 close 方法生效。
@Component
public class XianJian {
public void close() {
System.out.println("销毁啦!!德玛西亚 close ");
}
public void shutdown() {
System.out.println("销毁啦!!德玛西亚 shutdown ");
}
}
最后两种骚操作 源码如下,小伙伴们可以琢磨琢磨~
org.springframework.beans.factory.support.DisposableBeanAdapter#inferDestroyMethodIfNecessary
private static String inferDestroyMethodIfNecessary(Object bean, RootBeanDefinition beanDefinition) {
String destroyMethodName = beanDefinition.resolvedDestroyMethodName;
if (destroyMethodName == null) {
destroyMethodName = beanDefinition.getDestroyMethodName();
boolean autoCloseable = (bean instanceof AutoCloseable);
if (AbstractBeanDefinition.INFER_METHOD.equals(destroyMethodName) ||
(destroyMethodName == null && autoCloseable)) {
// Only perform destroy method inference in case of the bean
// not explicitly implementing the DisposableBean interface
destroyMethodName = null;
if (!(bean instanceof DisposableBean)) {
if (autoCloseable) {
destroyMethodName = CLOSE_METHOD_NAME;
}
else {
try {
destroyMethodName = bean.getClass().getMethod(CLOSE_METHOD_NAME).getName();
}
catch (NoSuchMethodException ex) {
try {
destroyMethodName = bean.getClass().getMethod(SHUTDOWN_METHOD_NAME).getName();
}
catch (NoSuchMethodException ex2) {
// no candidate destroy method found
}
}
}
}
}
beanDefinition.resolvedDestroyMethodName = (destroyMethodName != null ? destroyMethodName : "");
}
return (StringUtils.hasLength(destroyMethodName) ? destroyMethodName : null);
}
感谢笔芯ꔛꕤ