diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/DisposableBeanAdapter.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/DisposableBeanAdapter.java
index 512bbec6b3..98d2601fd1 100644
--- a/spring-beans/src/main/java/org/springframework/beans/factory/support/DisposableBeanAdapter.java
+++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/DisposableBeanAdapter.java
@@ -62,6 +62,8 @@ import org.springframework.util.StringUtils;
@SuppressWarnings("serial")
class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
+ private static final String DESTROY_METHOD_NAME = "destroy";
+
private static final String CLOSE_METHOD_NAME = "close";
private static final String SHUTDOWN_METHOD_NAME = "shutdown";
@@ -104,13 +106,16 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
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.invokeDisposableBean = (bean instanceof DisposableBean &&
+ !beanDefinition.isExternallyManagedDestroyMethod(DESTROY_METHOD_NAME));
this.nonPublicAccessAllowed = beanDefinition.isNonPublicAccessAllowed();
this.acc = acc;
+
String destroyMethodName = inferDestroyMethodIfNecessary(bean, beanDefinition);
- if (destroyMethodName != null && !(this.invokeDisposableBean && "destroy".equals(destroyMethodName)) &&
+ if (destroyMethodName != null &&
+ !(this.invokeDisposableBean && DESTROY_METHOD_NAME.equals(destroyMethodName)) &&
!beanDefinition.isExternallyManagedDestroyMethod(destroyMethodName)) {
+
this.destroyMethodName = destroyMethodName;
Method destroyMethod = determineDestroyMethod(destroyMethodName);
if (destroyMethod == null) {
@@ -135,6 +140,7 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
}
this.destroyMethod = destroyMethod;
}
+
this.beanPostProcessors = filterPostProcessors(postProcessors, bean);
}
@@ -349,8 +355,8 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
destroyMethodName = beanDefinition.getDestroyMethodName();
if (AbstractBeanDefinition.INFER_METHOD.equals(destroyMethodName) ||
(destroyMethodName == null && bean instanceof AutoCloseable)) {
- // Only perform destroy method inference or Closeable detection
- // in case of the bean not explicitly implementing DisposableBean
+ // Only perform destroy method inference in case of the bean
+ // not explicitly implementing the DisposableBean interface
destroyMethodName = null;
if (!(bean instanceof DisposableBean)) {
try {
diff --git a/spring-context/src/test/java/org/springframework/context/annotation/DestroyMethodInferenceTests.java b/spring-context/src/test/java/org/springframework/context/annotation/DestroyMethodInferenceTests.java
index 7da4675bed..c15abc241d 100644
--- a/spring-context/src/test/java/org/springframework/context/annotation/DestroyMethodInferenceTests.java
+++ b/spring-context/src/test/java/org/springframework/context/annotation/DestroyMethodInferenceTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2019 the original author or authors.
+ * Copyright 2002-2021 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.
@@ -26,7 +26,6 @@ import org.springframework.context.support.GenericXmlApplicationContext;
import static org.assertj.core.api.Assertions.assertThat;
-
/**
* @author Chris Beams
* @author Juergen Hoeller
@@ -47,6 +46,7 @@ public class DestroyMethodInferenceTests {
WithLocalShutdownMethod c7 = ctx.getBean("c7", WithLocalShutdownMethod.class);
WithInheritedCloseMethod c8 = ctx.getBean("c8", WithInheritedCloseMethod.class);
WithDisposableBean c9 = ctx.getBean("c9", WithDisposableBean.class);
+ WithAutoCloseable c10 = ctx.getBean("c10", WithAutoCloseable.class);
assertThat(c0.closed).as("c0").isFalse();
assertThat(c1.closed).as("c1").isFalse();
@@ -58,6 +58,8 @@ public class DestroyMethodInferenceTests {
assertThat(c7.closed).as("c7").isFalse();
assertThat(c8.closed).as("c8").isFalse();
assertThat(c9.closed).as("c9").isFalse();
+ assertThat(c10.closed).as("c10").isFalse();
+
ctx.close();
assertThat(c0.closed).as("c0").isTrue();
assertThat(c1.closed).as("c1").isTrue();
@@ -69,6 +71,7 @@ public class DestroyMethodInferenceTests {
assertThat(c7.closed).as("c7").isTrue();
assertThat(c8.closed).as("c8").isFalse();
assertThat(c9.closed).as("c9").isTrue();
+ assertThat(c10.closed).as("c10").isTrue();
}
@Test
@@ -80,21 +83,29 @@ public class DestroyMethodInferenceTests {
WithLocalCloseMethod x3 = ctx.getBean("x3", WithLocalCloseMethod.class);
WithNoCloseMethod x4 = ctx.getBean("x4", WithNoCloseMethod.class);
WithInheritedCloseMethod x8 = ctx.getBean("x8", WithInheritedCloseMethod.class);
+ WithDisposableBean x9 = ctx.getBean("x9", WithDisposableBean.class);
+ WithAutoCloseable x10 = ctx.getBean("x10", WithAutoCloseable.class);
assertThat(x1.closed).isFalse();
assertThat(x2.closed).isFalse();
assertThat(x3.closed).isFalse();
assertThat(x4.closed).isFalse();
+ assertThat(x8.closed).isFalse();
+ assertThat(x9.closed).isFalse();
+ assertThat(x10.closed).isFalse();
+
ctx.close();
assertThat(x1.closed).isFalse();
assertThat(x2.closed).isTrue();
assertThat(x3.closed).isTrue();
assertThat(x4.closed).isFalse();
assertThat(x8.closed).isFalse();
+ assertThat(x9.closed).isTrue();
+ assertThat(x10.closed).isTrue();
}
- @Configuration
+ @Configuration(proxyBeanMethods = false)
static class Config {
@Bean(destroyMethod = "explicitClose")
@@ -155,6 +166,11 @@ public class DestroyMethodInferenceTests {
public WithDisposableBean c9() {
return new WithDisposableBean();
}
+
+ @Bean
+ public WithAutoCloseable c10() {
+ return new WithAutoCloseable();
+ }
}
@@ -189,17 +205,6 @@ public class DestroyMethodInferenceTests {
}
- static class WithDisposableBean implements DisposableBean {
-
- boolean closed = false;
-
- @Override
- public void destroy() {
- closed = true;
- }
- }
-
-
static class WithNoCloseMethod {
boolean closed = false;
@@ -215,4 +220,26 @@ public class DestroyMethodInferenceTests {
}
}
+
+ static class WithDisposableBean implements DisposableBean {
+
+ boolean closed = false;
+
+ @Override
+ public void destroy() {
+ closed = true;
+ }
+ }
+
+
+ static class WithAutoCloseable implements AutoCloseable {
+
+ boolean closed = false;
+
+ @Override
+ public void close() {
+ closed = true;
+ }
+ }
+
}
diff --git a/spring-context/src/test/resources/org/springframework/context/annotation/DestroyMethodInferenceTests-context.xml b/spring-context/src/test/resources/org/springframework/context/annotation/DestroyMethodInferenceTests-context.xml
index 5c66a6d9e2..c72bd70db5 100644
--- a/spring-context/src/test/resources/org/springframework/context/annotation/DestroyMethodInferenceTests-context.xml
+++ b/spring-context/src/test/resources/org/springframework/context/annotation/DestroyMethodInferenceTests-context.xml
@@ -15,10 +15,16 @@
class="org.springframework.context.annotation.DestroyMethodInferenceTests.WithInheritedCloseMethod"
destroy-method=""/>
+
+
+
+
-