Skip to content

Commit 41ee233

Browse files
committed
Support for registering multiple init/destroy methods on AbstractBeanDefinition
Closes gh-28013
1 parent 8506778 commit 41ee233

File tree

6 files changed

+229
-136
lines changed

6 files changed

+229
-136
lines changed

spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java

+10-9
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,6 @@
7474
import org.springframework.core.PriorityOrdered;
7575
import org.springframework.core.ResolvableType;
7676
import org.springframework.lang.Nullable;
77-
import org.springframework.util.Assert;
7877
import org.springframework.util.ClassUtils;
7978
import org.springframework.util.ObjectUtils;
8079
import org.springframework.util.ReflectionUtils;
@@ -1789,11 +1788,15 @@ protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBea
17891788
}
17901789

17911790
if (mbd != null && bean.getClass() != NullBean.class) {
1792-
String initMethodName = mbd.getInitMethodName();
1793-
if (StringUtils.hasLength(initMethodName) &&
1794-
!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
1795-
!mbd.isExternallyManagedInitMethod(initMethodName)) {
1796-
invokeCustomInitMethod(beanName, bean, mbd);
1791+
String[] initMethodNames = mbd.getInitMethodNames();
1792+
if (initMethodNames != null) {
1793+
for (String initMethodName : initMethodNames) {
1794+
if (StringUtils.hasLength(initMethodName) &&
1795+
!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
1796+
!mbd.isExternallyManagedInitMethod(initMethodName)) {
1797+
invokeCustomInitMethod(beanName, bean, mbd, initMethodName);
1798+
}
1799+
}
17971800
}
17981801
}
17991802
}
@@ -1805,11 +1808,9 @@ protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBea
18051808
* methods with arguments.
18061809
* @see #invokeInitMethods
18071810
*/
1808-
protected void invokeCustomInitMethod(String beanName, Object bean, RootBeanDefinition mbd)
1811+
protected void invokeCustomInitMethod(String beanName, Object bean, RootBeanDefinition mbd, String initMethodName)
18091812
throws Throwable {
18101813

1811-
String initMethodName = mbd.getInitMethodName();
1812-
Assert.state(initMethodName != null, "No init method set");
18131814
Method initMethod = (mbd.isNonPublicAccessAllowed() ?
18141815
BeanUtils.findMethod(bean.getClass(), initMethodName) :
18151816
ClassUtils.getMethodIfAvailable(bean.getClass(), initMethodName));

spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanDefinition.java

+59-19
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2021 the original author or authors.
2+
* Copyright 2002-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -184,10 +184,10 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess
184184
private MethodOverrides methodOverrides = new MethodOverrides();
185185

186186
@Nullable
187-
private String initMethodName;
187+
private String[] initMethodNames;
188188

189189
@Nullable
190-
private String destroyMethodName;
190+
private String[] destroyMethodNames;
191191

192192
private boolean enforceInitMethod = true;
193193

@@ -262,9 +262,9 @@ protected AbstractBeanDefinition(BeanDefinition original) {
262262
setInstanceSupplier(originalAbd.getInstanceSupplier());
263263
setNonPublicAccessAllowed(originalAbd.isNonPublicAccessAllowed());
264264
setLenientConstructorResolution(originalAbd.isLenientConstructorResolution());
265-
setInitMethodName(originalAbd.getInitMethodName());
265+
setInitMethodNames(originalAbd.getInitMethodNames());
266266
setEnforceInitMethod(originalAbd.isEnforceInitMethod());
267-
setDestroyMethodName(originalAbd.getDestroyMethodName());
267+
setDestroyMethodNames(originalAbd.getDestroyMethodNames());
268268
setEnforceDestroyMethod(originalAbd.isEnforceDestroyMethod());
269269
setSynthetic(originalAbd.isSynthetic());
270270
setResource(originalAbd.getResource());
@@ -338,12 +338,12 @@ public void overrideFrom(BeanDefinition other) {
338338
setInstanceSupplier(otherAbd.getInstanceSupplier());
339339
setNonPublicAccessAllowed(otherAbd.isNonPublicAccessAllowed());
340340
setLenientConstructorResolution(otherAbd.isLenientConstructorResolution());
341-
if (otherAbd.getInitMethodName() != null) {
342-
setInitMethodName(otherAbd.getInitMethodName());
341+
if (otherAbd.getInitMethodNames() != null) {
342+
setInitMethodNames(otherAbd.getInitMethodNames());
343343
setEnforceInitMethod(otherAbd.isEnforceInitMethod());
344344
}
345-
if (otherAbd.getDestroyMethodName() != null) {
346-
setDestroyMethodName(otherAbd.getDestroyMethodName());
345+
if (otherAbd.getDestroyMethodNames() != null) {
346+
setDestroyMethodNames(otherAbd.getDestroyMethodNames());
347347
setEnforceDestroyMethod(otherAbd.isEnforceDestroyMethod());
348348
}
349349
setSynthetic(otherAbd.isSynthetic());
@@ -918,22 +918,42 @@ public boolean hasMethodOverrides() {
918918
return !this.methodOverrides.isEmpty();
919919
}
920920

921+
/**
922+
* Specify the names of multiple initializer methods.
923+
* <p>The default is {@code null} in which case there are no initializer methods.
924+
* @since 6.0
925+
* @see #setInitMethodName
926+
*/
927+
public void setInitMethodNames(@Nullable String... initMethodNames) {
928+
this.initMethodNames = initMethodNames;
929+
}
930+
931+
/**
932+
* Return the names of the initializer methods.
933+
* @since 6.0
934+
*/
935+
@Nullable
936+
public String[] getInitMethodNames() {
937+
return this.initMethodNames;
938+
}
939+
921940
/**
922941
* Set the name of the initializer method.
923942
* <p>The default is {@code null} in which case there is no initializer method.
943+
* @see #setInitMethodNames
924944
*/
925945
@Override
926946
public void setInitMethodName(@Nullable String initMethodName) {
927-
this.initMethodName = initMethodName;
947+
this.initMethodNames = (initMethodName != null ? new String[] {initMethodName} : null);
928948
}
929949

930950
/**
931-
* Return the name of the initializer method.
951+
* Return the name of the initializer method (the first one in case of multiple methods).
932952
*/
933953
@Override
934954
@Nullable
935955
public String getInitMethodName() {
936-
return this.initMethodName;
956+
return (!ObjectUtils.isEmpty(this.initMethodNames) ? this.initMethodNames[0] : null);
937957
}
938958

939959
/**
@@ -957,22 +977,42 @@ public boolean isEnforceInitMethod() {
957977
return this.enforceInitMethod;
958978
}
959979

980+
/**
981+
* Specify the names of multiple destroy methods.
982+
* <p>The default is {@code null} in which case there are no destroy methods.
983+
* @since 6.0
984+
* @see #setDestroyMethodName
985+
*/
986+
public void setDestroyMethodNames(@Nullable String... destroyMethodNames) {
987+
this.destroyMethodNames = destroyMethodNames;
988+
}
989+
990+
/**
991+
* Return the names of the destroy methods.
992+
* @since 6.0
993+
*/
994+
@Nullable
995+
public String[] getDestroyMethodNames() {
996+
return this.destroyMethodNames;
997+
}
998+
960999
/**
9611000
* Set the name of the destroy method.
9621001
* <p>The default is {@code null} in which case there is no destroy method.
1002+
* @see #setDestroyMethodNames
9631003
*/
9641004
@Override
9651005
public void setDestroyMethodName(@Nullable String destroyMethodName) {
966-
this.destroyMethodName = destroyMethodName;
1006+
this.destroyMethodNames = (destroyMethodName != null ? new String[] {destroyMethodName} : null);
9671007
}
9681008

9691009
/**
970-
* Return the name of the destroy method.
1010+
* Return the name of the destroy method (the first one in case of multiple methods).
9711011
*/
9721012
@Override
9731013
@Nullable
9741014
public String getDestroyMethodName() {
975-
return this.destroyMethodName;
1015+
return (!ObjectUtils.isEmpty(this.destroyMethodNames) ? this.destroyMethodNames[0] : null);
9761016
}
9771017

9781018
/**
@@ -1189,9 +1229,9 @@ public boolean equals(@Nullable Object other) {
11891229
ObjectUtils.nullSafeEquals(this.methodOverrides, that.methodOverrides) &&
11901230
ObjectUtils.nullSafeEquals(this.factoryBeanName, that.factoryBeanName) &&
11911231
ObjectUtils.nullSafeEquals(this.factoryMethodName, that.factoryMethodName) &&
1192-
ObjectUtils.nullSafeEquals(this.initMethodName, that.initMethodName) &&
1232+
ObjectUtils.nullSafeEquals(this.initMethodNames, that.initMethodNames) &&
11931233
this.enforceInitMethod == that.enforceInitMethod &&
1194-
ObjectUtils.nullSafeEquals(this.destroyMethodName, that.destroyMethodName) &&
1234+
ObjectUtils.nullSafeEquals(this.destroyMethodNames, that.destroyMethodNames) &&
11951235
this.enforceDestroyMethod == that.enforceDestroyMethod &&
11961236
this.synthetic == that.synthetic &&
11971237
this.role == that.role &&
@@ -1241,8 +1281,8 @@ public String toString() {
12411281
sb.append("; primary=").append(this.primary);
12421282
sb.append("; factoryBeanName=").append(this.factoryBeanName);
12431283
sb.append("; factoryMethodName=").append(this.factoryMethodName);
1244-
sb.append("; initMethodName=").append(this.initMethodName);
1245-
sb.append("; destroyMethodName=").append(this.destroyMethodName);
1284+
sb.append("; initMethodNames=").append(this.initMethodNames);
1285+
sb.append("; destroyMethodNames=").append(this.destroyMethodNames);
12461286
if (this.resource != null) {
12471287
sb.append("; defined in ").append(this.resource.getDescription());
12481288
}

0 commit comments

Comments
 (0)