@PostConstruct works for multiple private init methods of the same name in a hierarchy (SPR-5945)

This commit is contained in:
Juergen Hoeller 2009-07-22 12:52:47 +00:00
parent 9696c66517
commit 4deef3796e
2 changed files with 43 additions and 4 deletions

View File

@ -20,6 +20,7 @@ import java.io.Serializable;
import java.lang.annotation.Annotation; import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Iterator; import java.util.Iterator;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.Map; import java.util.Map;
@ -118,7 +119,7 @@ public class InitDestroyAnnotationBeanPostProcessor
if (beanType != null) { if (beanType != null) {
LifecycleMetadata metadata = findLifecycleMetadata(beanType); LifecycleMetadata metadata = findLifecycleMetadata(beanType);
for (Iterator<LifecycleElement> it = metadata.getInitMethods().iterator(); it.hasNext();) { for (Iterator<LifecycleElement> it = metadata.getInitMethods().iterator(); it.hasNext();) {
String methodName = it.next().getMethod().getName(); String methodName = calculateMethodIdentifierInHierarchy(it.next().getMethod());
if (!beanDefinition.isExternallyManagedInitMethod(methodName)) { if (!beanDefinition.isExternallyManagedInitMethod(methodName)) {
beanDefinition.registerExternallyManagedInitMethod(methodName); beanDefinition.registerExternallyManagedInitMethod(methodName);
} }
@ -127,7 +128,7 @@ public class InitDestroyAnnotationBeanPostProcessor
} }
} }
for (Iterator<LifecycleElement> it = metadata.getDestroyMethods().iterator(); it.hasNext();) { for (Iterator<LifecycleElement> it = metadata.getDestroyMethods().iterator(); it.hasNext();) {
String methodName = it.next().getMethod().getName(); String methodName = calculateMethodIdentifierInHierarchy(it.next().getMethod());
if (!beanDefinition.isExternallyManagedDestroyMethod(methodName)) { if (!beanDefinition.isExternallyManagedDestroyMethod(methodName)) {
beanDefinition.registerExternallyManagedDestroyMethod(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) { private LifecycleMetadata findLifecycleMetadata(Class clazz) {
if (this.lifecycleMetadataCache == null) { if (this.lifecycleMetadataCache == null) {
// Happens after deserialization, during destruction... // Happens after deserialization, during destruction...
@ -299,8 +309,15 @@ public class InitDestroyAnnotationBeanPostProcessor
@Override @Override
public boolean equals(Object other) { public boolean equals(Object other) {
return (this == other || (other instanceof LifecycleElement && if (this == other) {
this.method.getName().equals(((LifecycleElement) other).method.getName()))); 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 @Override

View File

@ -113,11 +113,13 @@ public class CommonAnnotationBeanPostProcessorTests {
ResourceInjectionBean bean = (ResourceInjectionBean) bf.getBean("annotatedBean"); ResourceInjectionBean bean = (ResourceInjectionBean) bf.getBean("annotatedBean");
assertTrue(bean.initCalled); assertTrue(bean.initCalled);
assertTrue(bean.init2Called); assertTrue(bean.init2Called);
assertTrue(bean.init3Called);
assertSame(tb, bean.getTestBean()); assertSame(tb, bean.getTestBean());
assertSame(tb2, bean.getTestBean2()); assertSame(tb2, bean.getTestBean2());
bf.destroySingletons(); bf.destroySingletons();
assertTrue(bean.destroyCalled); assertTrue(bean.destroyCalled);
assertTrue(bean.destroy2Called); assertTrue(bean.destroy2Called);
assertTrue(bean.destroy3Called);
} }
@Test @Test
@ -338,8 +340,12 @@ public class CommonAnnotationBeanPostProcessorTests {
public boolean init2Called = false; public boolean init2Called = false;
public boolean init3Called = false;
public boolean destroy2Called = false; public boolean destroy2Called = false;
public boolean destroy3Called = false;
@Resource @Resource
private TestBean testBean; private TestBean testBean;
@ -356,6 +362,14 @@ public class CommonAnnotationBeanPostProcessorTests {
this.init2Called = true; this.init2Called = true;
} }
@PostConstruct
private void init() {
if (this.init3Called) {
throw new IllegalStateException("Already called");
}
this.init3Called = true;
}
@PreDestroy @PreDestroy
protected void destroy2() { protected void destroy2() {
if (this.destroy2Called) { if (this.destroy2Called) {
@ -364,6 +378,14 @@ public class CommonAnnotationBeanPostProcessorTests {
this.destroy2Called = true; this.destroy2Called = true;
} }
@PreDestroy
private void destroy() {
if (this.destroy3Called) {
throw new IllegalStateException("Already called");
}
this.destroy3Called = true;
}
@Resource @Resource
public void setTestBean2(TestBean testBean2) { public void setTestBean2(TestBean testBean2) {
if (this.testBean2 != null) { if (this.testBean2 != null) {