Revert "Make sure inferred destroy method is set on the original bean definition"

This reverts commit 2e1538a20b.
This commit is contained in:
Stephane Nicoll 2022-08-09 11:31:56 +02:00
parent cd2b7afc87
commit 0a9db7cc47
5 changed files with 22 additions and 49 deletions

View File

@ -41,9 +41,7 @@ import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.beans.factory.aot.BeanRegistrationAotContribution;
import org.springframework.beans.factory.aot.BeanRegistrationAotProcessor;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.DestructionAwareBeanPostProcessor;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.MergedBeanDefinitionPostProcessor;
import org.springframework.beans.factory.support.RegisteredBean;
import org.springframework.beans.factory.support.RootBeanDefinition;
@ -160,30 +158,20 @@ public class InitDestroyAnnotationBeanPostProcessor implements DestructionAwareB
@Override
public BeanRegistrationAotContribution processAheadOfTime(RegisteredBean registeredBean) {
AbstractBeanDefinition beanDefinition = getOriginalBeanDefinition(registeredBean);
if (beanDefinition != null) {
RootBeanDefinition mergedBeanDefinition = registeredBean.getMergedBeanDefinition();
beanDefinition.resolveDestroyMethodIfNecessary();
LifecycleMetadata metadata = findInjectionMetadata(mergedBeanDefinition, registeredBean.getBeanClass());
if (!CollectionUtils.isEmpty(metadata.initMethods)) {
String[] initMethodNames = safeMerge(beanDefinition.getInitMethodNames(), metadata.initMethods);
beanDefinition.setInitMethodNames(initMethodNames);
}
if (!CollectionUtils.isEmpty(metadata.destroyMethods)) {
String[] destroyMethodNames = safeMerge(beanDefinition.getDestroyMethodNames(), metadata.destroyMethods);
beanDefinition.setDestroyMethodNames(destroyMethodNames);
}
registeredBean.getBeanFactory().clearMetadataCache();
RootBeanDefinition beanDefinition = registeredBean.getMergedBeanDefinition();
beanDefinition.resolveDestroyMethodIfNecessary();
LifecycleMetadata metadata = findInjectionMetadata(beanDefinition, registeredBean.getBeanClass());
if (!CollectionUtils.isEmpty(metadata.initMethods)) {
String[] initMethodNames = safeMerge(beanDefinition.getInitMethodNames(), metadata.initMethods);
beanDefinition.setInitMethodNames(initMethodNames);
}
if (!CollectionUtils.isEmpty(metadata.destroyMethods)) {
String[] destroyMethodNames = safeMerge(beanDefinition.getDestroyMethodNames(), metadata.destroyMethods);
beanDefinition.setDestroyMethodNames(destroyMethodNames);
}
return null;
}
@Nullable
private AbstractBeanDefinition getOriginalBeanDefinition(RegisteredBean registeredBean) {
BeanDefinition beanDefinition = registeredBean.getBeanFactory().getBeanDefinition(registeredBean.getBeanName());
return (beanDefinition instanceof AbstractBeanDefinition abd ? abd : null);
}
private LifecycleMetadata findInjectionMetadata(RootBeanDefinition beanDefinition, Class<?> beanType) {
LifecycleMetadata metadata = findLifecycleMetadata(beanType);
metadata.checkConfigMembers(beanDefinition);

View File

@ -1186,14 +1186,6 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess
}
}
/**
* Resolve the inferred destroy method if necessary.
* @since 6.0
*/
public void resolveDestroyMethodIfNecessary() {
setDestroyMethodNames(DisposableBeanAdapter
.inferDestroyMethodsIfNecessary(getResolvableType().toClass(), this));
}
/**
* Public declaration of Object's {@code clone()} method.

View File

@ -344,14 +344,13 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
* interfaces, reflectively calling the "close" method on implementing beans as well.
*/
@Nullable
static String[] inferDestroyMethodsIfNecessary(Class<?> target, AbstractBeanDefinition beanDefinition) {
static String[] inferDestroyMethodsIfNecessary(Class<?> target, RootBeanDefinition beanDefinition) {
String[] destroyMethodNames = beanDefinition.getDestroyMethodNames();
if (destroyMethodNames != null && destroyMethodNames.length > 1) {
return destroyMethodNames;
}
String destroyMethodName = (beanDefinition instanceof RootBeanDefinition rbd
? rbd.resolvedDestroyMethodName : null);
String destroyMethodName = beanDefinition.resolvedDestroyMethodName;
if (destroyMethodName == null) {
destroyMethodName = beanDefinition.getDestroyMethodName();
boolean autoCloseable = (AutoCloseable.class.isAssignableFrom(target));
@ -379,9 +378,7 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
}
}
}
if (beanDefinition instanceof RootBeanDefinition rbd) {
rbd.resolvedDestroyMethodName = (destroyMethodName != null ? destroyMethodName : "");
}
beanDefinition.resolvedDestroyMethodName = (destroyMethodName != null ? destroyMethodName : "");
}
return (StringUtils.hasLength(destroyMethodName) ? new String[] {destroyMethodName} : null);
}

View File

@ -550,6 +550,15 @@ public class RootBeanDefinition extends AbstractBeanDefinition {
}
}
/**
* Resolve the inferred destroy method if necessary.
* @since 6.0
*/
public void resolveDestroyMethodIfNecessary() {
setDestroyMethodNames(DisposableBeanAdapter
.inferDestroyMethodsIfNecessary(getResolvableType().toClass(), this));
}
/**
* Register an externally managed configuration destruction method &mdash;
* for example, a method annotated with JSR-250's

View File

@ -90,19 +90,6 @@ class InitDestroyAnnotationBeanPostProcessorTests {
assertThat(mergedBeanDefinition.getDestroyMethodNames()).containsExactly("close");
}
@Test
void processAheadOfTimeWhenHasInferredDestroyMethodIsRetainedIfMergedBeanDefinitionIsStale() {
RootBeanDefinition beanDefinition = new RootBeanDefinition(InferredDestroyBean.class);
beanDefinition.setDestroyMethodNames(AbstractBeanDefinition.INFER_METHOD);
processAheadOfTime(beanDefinition);
RootBeanDefinition mergedBeanDefinition = getMergedBeanDefinition();
assertThat(mergedBeanDefinition.getInitMethodNames()).isNull();
assertThat(mergedBeanDefinition.getDestroyMethodNames()).containsExactly("close");
RootBeanDefinition originalBeanDefinition = (RootBeanDefinition) this.beanFactory.getBeanDefinition("test");
assertThat(originalBeanDefinition.getInitMethodNames()).isNull();
assertThat(originalBeanDefinition.getDestroyMethodNames()).containsExactly("close");
}
@Test
void processAheadOfTimeWhenHasInferredDestroyMethodAndNoCandidateDoesNotMutateRootBeanDefinition() {
RootBeanDefinition beanDefinition = new RootBeanDefinition(NoInitDestroyBean.class);