diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java index a3945a679cb..25b4d94a2a0 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java @@ -1795,10 +1795,11 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac } /** - * Give a bean a chance to react now all its properties are set, + * Give a bean a chance to initialize itself after all its properties are set, * and a chance to know about its owning bean factory (this object). - * This means checking whether the bean implements InitializingBean or defines - * a custom init method, and invoking the necessary callback(s) if it does. + *
This means checking whether the bean implements {@link InitializingBean}
+ * or defines any custom init methods, and invoking the necessary callback(s)
+ * if it does.
* @param beanName the bean name in the factory (for debugging purposes)
* @param bean the new bean instance we may need to initialize
* @param mbd the merged bean definition that the bean was created with
@@ -1861,7 +1862,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
}
if (logger.isTraceEnabled()) {
- logger.trace("Invoking init method '" + initMethodName + "' on bean with name '" + beanName + "'");
+ logger.trace("Invoking init method '" + initMethodName + "' on bean with name '" + beanName + "'");
}
Method methodToInvoke = ClassUtils.getInterfaceMethodIfPossible(initMethod, bean.getClass());
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 cf04f0e8f55..d3330218073 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
@@ -263,15 +263,15 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
@Nullable
- private Method determineDestroyMethod(String name) {
+ private Method determineDestroyMethod(String destroyMethodName) {
try {
Class> beanClass = this.bean.getClass();
- Method destroyMethod = findDestroyMethod(beanClass, name);
+ Method destroyMethod = findDestroyMethod(beanClass, destroyMethodName);
if (destroyMethod != null) {
return destroyMethod;
}
for (Class> beanInterface : beanClass.getInterfaces()) {
- destroyMethod = findDestroyMethod(beanInterface, name);
+ destroyMethod = findDestroyMethod(beanInterface, destroyMethodName);
if (destroyMethod != null) {
return destroyMethod;
}
diff --git a/spring-beans/src/test/java/org/springframework/beans/factory/aot/BeanDefinitionPropertiesCodeGeneratorTests.java b/spring-beans/src/test/java/org/springframework/beans/factory/aot/BeanDefinitionPropertiesCodeGeneratorTests.java
index e9e84fabbad..64cab3e0ea6 100644
--- a/spring-beans/src/test/java/org/springframework/beans/factory/aot/BeanDefinitionPropertiesCodeGeneratorTests.java
+++ b/spring-beans/src/test/java/org/springframework/beans/factory/aot/BeanDefinitionPropertiesCodeGeneratorTests.java
@@ -28,6 +28,8 @@ import java.util.function.Supplier;
import javax.lang.model.element.Modifier;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.springframework.aot.generate.GeneratedClass;
@@ -61,6 +63,8 @@ import static org.assertj.core.api.Assertions.assertThat;
* @author Phillip Webb
* @author Stephane Nicoll
* @author Olga Maciaszek-Sharma
+ * @author Sam Brannen
+ * @since 6.0
*/
class BeanDefinitionPropertiesCodeGeneratorTests {
@@ -212,56 +216,6 @@ class BeanDefinitionPropertiesCodeGeneratorTests {
compile((actual, compiled) -> assertThat(actual.getRole()).isEqualTo(999));
}
- @Test
- void setInitMethodWhenSingleInitMethod() {
- this.beanDefinition.setTargetType(InitDestroyBean.class);
- this.beanDefinition.setInitMethodName("i1");
- compile((actual, compiled) -> assertThat(actual.getInitMethodNames()).containsExactly("i1"));
- assertHasMethodInvokeHints(InitDestroyBean.class, "i1");
- }
-
- @Test
- void setInitMethodWhenNoInitMethod() {
- this.beanDefinition.setTargetType(InitDestroyBean.class);
- compile((actual, compiled) -> assertThat(actual.getInitMethodNames()).isNull());
- }
-
- @Test
- void setInitMethodWhenMultipleInitMethods() {
- this.beanDefinition.setTargetType(InitDestroyBean.class);
- this.beanDefinition.setInitMethodNames("i1", "i2");
- compile((actual, compiled) -> assertThat(actual.getInitMethodNames()).containsExactly("i1", "i2"));
- assertHasMethodInvokeHints(InitDestroyBean.class, "i1", "i2");
- }
-
- @Test
- void setDestroyMethodWhenDestroyInitMethod() {
- this.beanDefinition.setTargetType(InitDestroyBean.class);
- this.beanDefinition.setDestroyMethodName("d1");
- compile((actual, compiled) -> assertThat(actual.getDestroyMethodNames()).containsExactly("d1"));
- assertHasMethodInvokeHints(InitDestroyBean.class, "d1");
- }
-
- @Test
- void setDestroyMethodWhenNoDestroyMethod() {
- this.beanDefinition.setTargetType(InitDestroyBean.class);
- compile((actual, compiled) -> assertThat(actual.getDestroyMethodNames()).isNull());
- }
-
- @Test
- void setDestroyMethodWhenMultipleDestroyMethods() {
- this.beanDefinition.setTargetType(InitDestroyBean.class);
- this.beanDefinition.setDestroyMethodNames("d1", "d2");
- compile((actual, compiled) -> assertThat(actual.getDestroyMethodNames()).containsExactly("d1", "d2"));
- assertHasMethodInvokeHints(InitDestroyBean.class, "d1", "d2");
- }
-
- private void assertHasMethodInvokeHints(Class> beanType, String... methodNames) {
- assertThat(methodNames).allMatch(methodName -> RuntimeHintsPredicates.reflection()
- .onMethod(beanType, methodName).invoke()
- .test(this.generationContext.getRuntimeHints()));
- }
-
@Test
void constructorArgumentValuesWhenValues() {
this.beanDefinition.getConstructorArgumentValues().addIndexedArgumentValue(0, String.class);
@@ -419,6 +373,60 @@ class BeanDefinitionPropertiesCodeGeneratorTests {
});
}
+ @Nested
+ class InitDestroyMethodTests {
+
+ @BeforeEach
+ void setTargetType() {
+ beanDefinition.setTargetType(InitDestroyBean.class);
+ }
+
+ @Test
+ void noInitMethod() {
+ compile((beanDef, compiled) -> assertThat(beanDef.getInitMethodNames()).isNull());
+ }
+
+ @Test
+ void singleInitMethod() {
+ beanDefinition.setInitMethodName("init");
+ compile((beanDef, compiled) -> assertThat(beanDef.getInitMethodNames()).containsExactly("init"));
+ assertHasMethodInvokeHints(InitDestroyBean.class, "init");
+ }
+
+ @Test
+ void multipleInitMethods() {
+ beanDefinition.setInitMethodNames("init", "init2");
+ compile((beanDef, compiled) -> assertThat(beanDef.getInitMethodNames()).containsExactly("init", "init2"));
+ assertHasMethodInvokeHints(InitDestroyBean.class, "init", "init2");
+ }
+
+ @Test
+ void noDestroyMethod() {
+ compile((beanDef, compiled) -> assertThat(beanDef.getDestroyMethodNames()).isNull());
+ }
+
+ @Test
+ void singleDestroyMethod() {
+ beanDefinition.setDestroyMethodName("destroy");
+ compile((beanDef, compiled) -> assertThat(beanDef.getDestroyMethodNames()).containsExactly("destroy"));
+ assertHasMethodInvokeHints(InitDestroyBean.class, "destroy");
+ }
+
+ @Test
+ void multipleDestroyMethods() {
+ beanDefinition.setDestroyMethodNames("destroy", "destroy2");
+ compile((beanDef, compiled) -> assertThat(beanDef.getDestroyMethodNames()).containsExactly("destroy", "destroy2"));
+ assertHasMethodInvokeHints(InitDestroyBean.class, "destroy", "destroy2");
+ }
+
+ }
+
+ private void assertHasMethodInvokeHints(Class> beanType, String... methodNames) {
+ assertThat(methodNames).allMatch(methodName -> RuntimeHintsPredicates.reflection()
+ .onMethod(beanType, methodName).invoke()
+ .test(this.generationContext.getRuntimeHints()));
+ }
+
private void compile(BiConsumer