diff --git a/spring-context/src/main/java/org/springframework/context/annotation/Bean.java b/spring-context/src/main/java/org/springframework/context/annotation/Bean.java index b15b7c8ef8..4d82f5d17c 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/Bean.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/Bean.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 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. @@ -157,8 +157,8 @@ import org.springframework.core.annotation.AliasFor; * *
* @Bean - * public static PropertyPlaceholderConfigurer ppc() { - * // instantiate, configure and return ppc ... + * public static PropertySourcesPlaceholderConfigurer pspc() { + * // instantiate, configure and return pspc ... * } ** @@ -228,6 +228,8 @@ public @interface Bean { * Not commonly used, given that the method may be called programmatically directly * within the body of a Bean-annotated method. *
The default value is {@code ""}, indicating no init method to be called. + * @see org.springframework.beans.factory.InitializingBean + * @see org.springframework.context.ConfigurableApplicationContext#refresh() */ String initMethod() default ""; @@ -248,12 +250,14 @@ public @interface Bean { * creation time). *
To disable destroy method inference for a particular {@code @Bean}, specify an * empty string as the value, e.g. {@code @Bean(destroyMethod="")}. Note that the - * {@link org.springframework.beans.factory.DisposableBean} and the - * {@link java.io.Closeable}/{@link java.lang.AutoCloseable} interfaces will - * nevertheless get detected and the corresponding destroy/close method invoked. + * {@link org.springframework.beans.factory.DisposableBean} callback interface will + * nevertheless get detected and the corresponding destroy method invoked: In other + * words, {@code destroyMethod=""} only affects custom close/shutdown methods and + * {@link java.io.Closeable}/{@link java.lang.AutoCloseable} declared close methods. *
Note: Only invoked on beans whose lifecycle is under the full control of the * factory, which is always the case for singletons but not guaranteed for any * other scope. + * @see org.springframework.beans.factory.DisposableBean * @see org.springframework.context.ConfigurableApplicationContext#close() */ String destroyMethod() default AbstractBeanDefinition.INFER_METHOD; 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 a9b1bf8829..ff94112794 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-2015 the original author or authors. + * Copyright 2002-2017 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. @@ -17,10 +17,10 @@ package org.springframework.context.annotation; import java.io.Closeable; -import java.io.IOException; import org.junit.Test; +import org.springframework.beans.factory.DisposableBean; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.support.GenericXmlApplicationContext; @@ -36,8 +36,7 @@ public class DestroyMethodInferenceTests { @Test public void beanMethods() { - ConfigurableApplicationContext ctx = - new AnnotationConfigApplicationContext(Config.class); + ConfigurableApplicationContext ctx = new AnnotationConfigApplicationContext(Config.class); WithExplicitDestroyMethod c0 = ctx.getBean(WithExplicitDestroyMethod.class); WithLocalCloseMethod c1 = ctx.getBean("c1", WithLocalCloseMethod.class); WithLocalCloseMethod c2 = ctx.getBean("c2", WithLocalCloseMethod.class); @@ -47,6 +46,7 @@ public class DestroyMethodInferenceTests { WithNoCloseMethod c6 = ctx.getBean("c6", WithNoCloseMethod.class); WithLocalShutdownMethod c7 = ctx.getBean("c7", WithLocalShutdownMethod.class); WithInheritedCloseMethod c8 = ctx.getBean("c8", WithInheritedCloseMethod.class); + WithDisposableBean c9 = ctx.getBean("c9", WithDisposableBean.class); assertThat(c0.closed, is(false)); assertThat(c1.closed, is(false)); @@ -57,6 +57,7 @@ public class DestroyMethodInferenceTests { assertThat(c6.closed, is(false)); assertThat(c7.closed, is(false)); assertThat(c8.closed, is(false)); + assertThat(c9.closed, is(false)); ctx.close(); assertThat("c0", c0.closed, is(true)); assertThat("c1", c1.closed, is(true)); @@ -67,6 +68,7 @@ public class DestroyMethodInferenceTests { assertThat("c6", c6.closed, is(false)); assertThat("c7", c7.closed, is(true)); assertThat("c8", c8.closed, is(false)); + assertThat("c9", c9.closed, is(true)); } @Test @@ -91,9 +93,11 @@ public class DestroyMethodInferenceTests { assertThat(x8.closed, is(false)); } + @Configuration static class Config { - @Bean(destroyMethod="explicitClose") + + @Bean(destroyMethod = "explicitClose") public WithExplicitDestroyMethod c0() { return new WithExplicitDestroyMethod(); } @@ -118,12 +122,12 @@ public class DestroyMethodInferenceTests { return new WithInheritedCloseMethod(); } - @Bean(destroyMethod="other") + @Bean(destroyMethod = "other") public WithInheritedCloseMethod c5() { return new WithInheritedCloseMethod() { @Override - public void close() throws IOException { - throw new RuntimeException("close() should not be called"); + public void close() { + throw new IllegalStateException("close() should not be called"); } @SuppressWarnings("unused") public void other() { @@ -146,37 +150,66 @@ public class DestroyMethodInferenceTests { public WithInheritedCloseMethod c8() { return new WithInheritedCloseMethod(); } + + @Bean(destroyMethod = "") + public WithDisposableBean c9() { + return new WithDisposableBean(); + } } static class WithExplicitDestroyMethod { + boolean closed = false; + public void explicitClose() { closed = true; } } + static class WithLocalCloseMethod { + boolean closed = false; + public void close() { closed = true; } } + static class WithInheritedCloseMethod implements Closeable { + boolean closed = false; + @Override - public void close() throws IOException { + public void close() { closed = true; } } + + static class WithDisposableBean implements DisposableBean { + + boolean closed = false; + + @Override + public void destroy() { + closed = true; + } + } + + static class WithNoCloseMethod { + boolean closed = false; } + static class WithLocalShutdownMethod { + boolean closed = false; + public void shutdown() { closed = true; }