From 4deef3796e728fa2fc7e4d3c688befdcbf000f29 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Wed, 22 Jul 2009 12:52:47 +0000 Subject: [PATCH] @PostConstruct works for multiple private init methods of the same name in a hierarchy (SPR-5945) --- ...nitDestroyAnnotationBeanPostProcessor.java | 25 ++++++++++++++++--- ...ommonAnnotationBeanPostProcessorTests.java | 22 ++++++++++++++++ 2 files changed, 43 insertions(+), 4 deletions(-) diff --git a/org.springframework.beans/src/main/java/org/springframework/beans/factory/annotation/InitDestroyAnnotationBeanPostProcessor.java b/org.springframework.beans/src/main/java/org/springframework/beans/factory/annotation/InitDestroyAnnotationBeanPostProcessor.java index 5652a74d150..01da4c0c20f 100644 --- a/org.springframework.beans/src/main/java/org/springframework/beans/factory/annotation/InitDestroyAnnotationBeanPostProcessor.java +++ b/org.springframework.beans/src/main/java/org/springframework/beans/factory/annotation/InitDestroyAnnotationBeanPostProcessor.java @@ -20,6 +20,7 @@ import java.io.Serializable; import java.lang.annotation.Annotation; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.lang.reflect.Modifier; import java.util.Iterator; import java.util.LinkedHashSet; import java.util.Map; @@ -118,7 +119,7 @@ public class InitDestroyAnnotationBeanPostProcessor if (beanType != null) { LifecycleMetadata metadata = findLifecycleMetadata(beanType); for (Iterator it = metadata.getInitMethods().iterator(); it.hasNext();) { - String methodName = it.next().getMethod().getName(); + String methodName = calculateMethodIdentifierInHierarchy(it.next().getMethod()); if (!beanDefinition.isExternallyManagedInitMethod(methodName)) { beanDefinition.registerExternallyManagedInitMethod(methodName); } @@ -127,7 +128,7 @@ public class InitDestroyAnnotationBeanPostProcessor } } for (Iterator it = metadata.getDestroyMethods().iterator(); it.hasNext();) { - String methodName = it.next().getMethod().getName(); + String methodName = calculateMethodIdentifierInHierarchy(it.next().getMethod()); if (!beanDefinition.isExternallyManagedDestroyMethod(methodName)) { beanDefinition.registerExternallyManagedDestroyMethod(methodName); } @@ -176,6 +177,15 @@ public class InitDestroyAnnotationBeanPostProcessor } + private String calculateMethodIdentifierInHierarchy(Method method) { + if (Modifier.isPrivate(method.getModifiers())) { + return method.getDeclaringClass() + "." + method.getName(); + } + else { + return method.getName(); + } + } + private LifecycleMetadata findLifecycleMetadata(Class clazz) { if (this.lifecycleMetadataCache == null) { // Happens after deserialization, during destruction... @@ -299,8 +309,15 @@ public class InitDestroyAnnotationBeanPostProcessor @Override public boolean equals(Object other) { - return (this == other || (other instanceof LifecycleElement && - this.method.getName().equals(((LifecycleElement) other).method.getName()))); + if (this == other) { + return true; + } + if (!(other instanceof LifecycleElement)) { + return false; + } + LifecycleElement otherElement = (LifecycleElement) other; + return (this.method.getName().equals(otherElement.method.getName()) && + this.method.getDeclaringClass().equals(otherElement.method.getDeclaringClass())); } @Override diff --git a/org.springframework.context/src/test/java/org/springframework/context/annotation/CommonAnnotationBeanPostProcessorTests.java b/org.springframework.context/src/test/java/org/springframework/context/annotation/CommonAnnotationBeanPostProcessorTests.java index 304f9ab85bd..3ba347023ea 100644 --- a/org.springframework.context/src/test/java/org/springframework/context/annotation/CommonAnnotationBeanPostProcessorTests.java +++ b/org.springframework.context/src/test/java/org/springframework/context/annotation/CommonAnnotationBeanPostProcessorTests.java @@ -113,11 +113,13 @@ public class CommonAnnotationBeanPostProcessorTests { ResourceInjectionBean bean = (ResourceInjectionBean) bf.getBean("annotatedBean"); assertTrue(bean.initCalled); assertTrue(bean.init2Called); + assertTrue(bean.init3Called); assertSame(tb, bean.getTestBean()); assertSame(tb2, bean.getTestBean2()); bf.destroySingletons(); assertTrue(bean.destroyCalled); assertTrue(bean.destroy2Called); + assertTrue(bean.destroy3Called); } @Test @@ -338,8 +340,12 @@ public class CommonAnnotationBeanPostProcessorTests { public boolean init2Called = false; + public boolean init3Called = false; + public boolean destroy2Called = false; + public boolean destroy3Called = false; + @Resource private TestBean testBean; @@ -356,6 +362,14 @@ public class CommonAnnotationBeanPostProcessorTests { this.init2Called = true; } + @PostConstruct + private void init() { + if (this.init3Called) { + throw new IllegalStateException("Already called"); + } + this.init3Called = true; + } + @PreDestroy protected void destroy2() { if (this.destroy2Called) { @@ -364,6 +378,14 @@ public class CommonAnnotationBeanPostProcessorTests { this.destroy2Called = true; } + @PreDestroy + private void destroy() { + if (this.destroy3Called) { + throw new IllegalStateException("Already called"); + } + this.destroy3Called = true; + } + @Resource public void setTestBean2(TestBean testBean2) { if (this.testBean2 != null) {