Skip to content

Commit d1b5b5d

Browse files
committed
Clarify destroy method suppression for DisposableBean vs (Auto)Closeable
Issue: SPR-16078 (cherry picked from commit dff2c84)
1 parent 2d05e53 commit d1b5b5d

File tree

2 files changed

+29
-6
lines changed

2 files changed

+29
-6
lines changed

spring-context/src/main/java/org/springframework/context/annotation/Bean.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,8 @@
228228
* Not commonly used, given that the method may be called programmatically directly
229229
* within the body of a Bean-annotated method.
230230
* <p>The default value is {@code ""}, indicating no init method to be called.
231+
* @see org.springframework.beans.factory.InitializingBean
232+
* @see org.springframework.context.ConfigurableApplicationContext#refresh()
231233
*/
232234
String initMethod() default "";
233235

@@ -248,12 +250,14 @@
248250
* creation time).
249251
* <p>To disable destroy method inference for a particular {@code @Bean}, specify an
250252
* empty string as the value, e.g. {@code @Bean(destroyMethod="")}. Note that the
251-
* {@link org.springframework.beans.factory.DisposableBean} and the
252-
* {@link java.io.Closeable}/{@link java.lang.AutoCloseable} interfaces will
253-
* nevertheless get detected and the corresponding destroy/close method invoked.
253+
* {@link org.springframework.beans.factory.DisposableBean} callback interface will
254+
* nevertheless get detected and the corresponding destroy method invoked: In other
255+
* words, {@code destroyMethod=""} only affects custom close/shutdown methods and
256+
* {@link java.io.Closeable}/{@link java.lang.AutoCloseable} declared close methods.
254257
* <p>Note: Only invoked on beans whose lifecycle is under the full control of the
255258
* factory, which is always the case for singletons but not guaranteed for any
256259
* other scope.
260+
* @see org.springframework.beans.factory.DisposableBean
257261
* @see org.springframework.context.ConfigurableApplicationContext#close()
258262
*/
259263
String destroyMethod() default AbstractBeanDefinition.INFER_METHOD;

spring-context/src/test/java/org/springframework/context/annotation/DestroyMethodInferenceTests.java

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@
1717
package org.springframework.context.annotation;
1818

1919
import java.io.Closeable;
20-
import java.io.IOException;
2120

2221
import org.junit.Test;
2322

23+
import org.springframework.beans.factory.DisposableBean;
2424
import org.springframework.context.ConfigurableApplicationContext;
2525
import org.springframework.context.support.GenericXmlApplicationContext;
2626

@@ -46,6 +46,7 @@ public void beanMethods() {
4646
WithNoCloseMethod c6 = ctx.getBean("c6", WithNoCloseMethod.class);
4747
WithLocalShutdownMethod c7 = ctx.getBean("c7", WithLocalShutdownMethod.class);
4848
WithInheritedCloseMethod c8 = ctx.getBean("c8", WithInheritedCloseMethod.class);
49+
WithDisposableBean c9 = ctx.getBean("c9", WithDisposableBean.class);
4950

5051
assertThat(c0.closed, is(false));
5152
assertThat(c1.closed, is(false));
@@ -56,6 +57,7 @@ public void beanMethods() {
5657
assertThat(c6.closed, is(false));
5758
assertThat(c7.closed, is(false));
5859
assertThat(c8.closed, is(false));
60+
assertThat(c9.closed, is(false));
5961
ctx.close();
6062
assertThat("c0", c0.closed, is(true));
6163
assertThat("c1", c1.closed, is(true));
@@ -66,6 +68,7 @@ public void beanMethods() {
6668
assertThat("c6", c6.closed, is(false));
6769
assertThat("c7", c7.closed, is(true));
6870
assertThat("c8", c8.closed, is(false));
71+
assertThat("c9", c9.closed, is(true));
6972
}
7073

7174
@Test
@@ -123,7 +126,7 @@ public Closeable c4() {
123126
public WithInheritedCloseMethod c5() {
124127
return new WithInheritedCloseMethod() {
125128
@Override
126-
public void close() throws IOException {
129+
public void close() {
127130
throw new IllegalStateException("close() should not be called");
128131
}
129132
@SuppressWarnings("unused")
@@ -147,6 +150,11 @@ public WithLocalShutdownMethod c7() {
147150
public WithInheritedCloseMethod c8() {
148151
return new WithInheritedCloseMethod();
149152
}
153+
154+
@Bean(destroyMethod = "")
155+
public WithDisposableBean c9() {
156+
return new WithDisposableBean();
157+
}
150158
}
151159

152160

@@ -175,7 +183,18 @@ static class WithInheritedCloseMethod implements Closeable {
175183
boolean closed = false;
176184

177185
@Override
178-
public void close() throws IOException {
186+
public void close() {
187+
closed = true;
188+
}
189+
}
190+
191+
192+
static class WithDisposableBean implements DisposableBean {
193+
194+
boolean closed = false;
195+
196+
@Override
197+
public void destroy() {
179198
closed = true;
180199
}
181200
}

0 commit comments

Comments
 (0)