Polishing
This commit is contained in:
parent
9b5cbc1334
commit
32f061a3e0
|
|
@ -1794,10 +1794,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).
|
* and a chance to know about its owning bean factory (this object).
|
||||||
* This means checking whether the bean implements InitializingBean or defines
|
* <p>This means checking whether the bean implements {@link InitializingBean}
|
||||||
* a custom init method, and invoking the necessary callback(s) if it does.
|
* 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 beanName the bean name in the factory (for debugging purposes)
|
||||||
* @param bean the new bean instance we may need to initialize
|
* @param bean the new bean instance we may need to initialize
|
||||||
* @param mbd the merged bean definition that the bean was created with
|
* @param mbd the merged bean definition that the bean was created with
|
||||||
|
|
@ -1860,7 +1861,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||||
}
|
}
|
||||||
|
|
||||||
if (logger.isTraceEnabled()) {
|
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());
|
Method methodToInvoke = ClassUtils.getInterfaceMethodIfPossible(initMethod, bean.getClass());
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -252,15 +252,15 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
|
||||||
|
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private Method determineDestroyMethod(String name) {
|
private Method determineDestroyMethod(String destroyMethodName) {
|
||||||
try {
|
try {
|
||||||
Class<?> beanClass = this.bean.getClass();
|
Class<?> beanClass = this.bean.getClass();
|
||||||
Method destroyMethod = findDestroyMethod(beanClass, name);
|
Method destroyMethod = findDestroyMethod(beanClass, destroyMethodName);
|
||||||
if (destroyMethod != null) {
|
if (destroyMethod != null) {
|
||||||
return destroyMethod;
|
return destroyMethod;
|
||||||
}
|
}
|
||||||
for (Class<?> beanInterface : beanClass.getInterfaces()) {
|
for (Class<?> beanInterface : beanClass.getInterfaces()) {
|
||||||
destroyMethod = findDestroyMethod(beanInterface, name);
|
destroyMethod = findDestroyMethod(beanInterface, destroyMethodName);
|
||||||
if (destroyMethod != null) {
|
if (destroyMethod != null) {
|
||||||
return destroyMethod;
|
return destroyMethod;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,8 @@ import java.util.function.Supplier;
|
||||||
|
|
||||||
import javax.lang.model.element.Modifier;
|
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.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import org.springframework.aot.generate.GeneratedClass;
|
import org.springframework.aot.generate.GeneratedClass;
|
||||||
|
|
@ -61,6 +63,8 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||||
* @author Phillip Webb
|
* @author Phillip Webb
|
||||||
* @author Stephane Nicoll
|
* @author Stephane Nicoll
|
||||||
* @author Olga Maciaszek-Sharma
|
* @author Olga Maciaszek-Sharma
|
||||||
|
* @author Sam Brannen
|
||||||
|
* @since 6.0
|
||||||
*/
|
*/
|
||||||
class BeanDefinitionPropertiesCodeGeneratorTests {
|
class BeanDefinitionPropertiesCodeGeneratorTests {
|
||||||
|
|
||||||
|
|
@ -212,56 +216,6 @@ class BeanDefinitionPropertiesCodeGeneratorTests {
|
||||||
compile((actual, compiled) -> assertThat(actual.getRole()).isEqualTo(999));
|
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
|
@Test
|
||||||
void constructorArgumentValuesWhenValues() {
|
void constructorArgumentValuesWhenValues() {
|
||||||
this.beanDefinition.getConstructorArgumentValues().addIndexedArgumentValue(0, String.class);
|
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<RootBeanDefinition, Compiled> result) {
|
private void compile(BiConsumer<RootBeanDefinition, Compiled> result) {
|
||||||
compile(attribute -> true, result);
|
compile(attribute -> true, result);
|
||||||
}
|
}
|
||||||
|
|
@ -450,16 +458,16 @@ class BeanDefinitionPropertiesCodeGeneratorTests {
|
||||||
|
|
||||||
static class InitDestroyBean {
|
static class InitDestroyBean {
|
||||||
|
|
||||||
void i1() {
|
void init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void i2() {
|
void init2() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void d1() {
|
void destroy() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void d2() {
|
void destroy2() {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -143,6 +143,7 @@ class InitDestroyMethodLifecycleTests {
|
||||||
assertThat(bean.initMethods).as("init-methods").containsExactly(
|
assertThat(bean.initMethods).as("init-methods").containsExactly(
|
||||||
"PackagePrivateInitDestroyBean.postConstruct",
|
"PackagePrivateInitDestroyBean.postConstruct",
|
||||||
"SubPackagePrivateInitDestroyBean.postConstruct",
|
"SubPackagePrivateInitDestroyBean.postConstruct",
|
||||||
|
"InitializingBean.afterPropertiesSet",
|
||||||
"initMethod"
|
"initMethod"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -150,6 +151,7 @@ class InitDestroyMethodLifecycleTests {
|
||||||
assertThat(bean.destroyMethods).as("destroy-methods").containsExactly(
|
assertThat(bean.destroyMethods).as("destroy-methods").containsExactly(
|
||||||
"SubPackagePrivateInitDestroyBean.preDestroy",
|
"SubPackagePrivateInitDestroyBean.preDestroy",
|
||||||
"PackagePrivateInitDestroyBean.preDestroy",
|
"PackagePrivateInitDestroyBean.preDestroy",
|
||||||
|
"DisposableBean.destroy",
|
||||||
"destroyMethod"
|
"destroyMethod"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -191,12 +193,12 @@ class InitDestroyMethodLifecycleTests {
|
||||||
InitializingBean, DisposableBean {
|
InitializingBean, DisposableBean {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void afterPropertiesSet() throws Exception {
|
public void afterPropertiesSet() {
|
||||||
this.initMethods.add("InitializingBean.afterPropertiesSet");
|
this.initMethods.add("InitializingBean.afterPropertiesSet");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void destroy() throws Exception {
|
public void destroy() {
|
||||||
this.destroyMethods.add("DisposableBean.destroy");
|
this.destroyMethods.add("DisposableBean.destroy");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -206,11 +208,11 @@ class InitDestroyMethodLifecycleTests {
|
||||||
final List<String> initMethods = new ArrayList<>();
|
final List<String> initMethods = new ArrayList<>();
|
||||||
final List<String> destroyMethods = new ArrayList<>();
|
final List<String> destroyMethods = new ArrayList<>();
|
||||||
|
|
||||||
public void customInit() throws Exception {
|
public void customInit() {
|
||||||
this.initMethods.add("customInit");
|
this.initMethods.add("customInit");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void customDestroy() throws Exception {
|
public void customDestroy() {
|
||||||
this.destroyMethods.add("customDestroy");
|
this.destroyMethods.add("customDestroy");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -218,12 +220,12 @@ class InitDestroyMethodLifecycleTests {
|
||||||
static class CustomAnnotatedPrivateInitDestroyBean extends CustomInitializingDisposableBean {
|
static class CustomAnnotatedPrivateInitDestroyBean extends CustomInitializingDisposableBean {
|
||||||
|
|
||||||
@PostConstruct
|
@PostConstruct
|
||||||
private void customInit1() throws Exception {
|
private void customInit1() {
|
||||||
this.initMethods.add("@PostConstruct.privateCustomInit1");
|
this.initMethods.add("@PostConstruct.privateCustomInit1");
|
||||||
}
|
}
|
||||||
|
|
||||||
@PreDestroy
|
@PreDestroy
|
||||||
private void customDestroy1() throws Exception {
|
private void customDestroy1() {
|
||||||
this.destroyMethods.add("@PreDestroy.privateCustomDestroy1");
|
this.destroyMethods.add("@PreDestroy.privateCustomDestroy1");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -232,13 +234,13 @@ class InitDestroyMethodLifecycleTests {
|
||||||
|
|
||||||
@PostConstruct
|
@PostConstruct
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
private void customInit1() throws Exception {
|
private void customInit1() {
|
||||||
this.initMethods.add("@PostConstruct.sameNameCustomInit1");
|
this.initMethods.add("@PostConstruct.sameNameCustomInit1");
|
||||||
}
|
}
|
||||||
|
|
||||||
@PreDestroy
|
@PreDestroy
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
private void customDestroy1() throws Exception {
|
private void customDestroy1() {
|
||||||
this.destroyMethods.add("@PreDestroy.sameNameCustomDestroy1");
|
this.destroyMethods.add("@PreDestroy.sameNameCustomDestroy1");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -247,12 +249,12 @@ class InitDestroyMethodLifecycleTests {
|
||||||
implements InitializingBean, DisposableBean {
|
implements InitializingBean, DisposableBean {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void afterPropertiesSet() throws Exception {
|
public void afterPropertiesSet() {
|
||||||
this.initMethods.add("afterPropertiesSet");
|
this.initMethods.add("afterPropertiesSet");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void destroy() throws Exception {
|
public void destroy() {
|
||||||
this.destroyMethods.add("destroy");
|
this.destroyMethods.add("destroy");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -260,12 +262,12 @@ class InitDestroyMethodLifecycleTests {
|
||||||
static class CustomAnnotatedInitDestroyBean extends CustomInitializingDisposableBean {
|
static class CustomAnnotatedInitDestroyBean extends CustomInitializingDisposableBean {
|
||||||
|
|
||||||
@PostConstruct
|
@PostConstruct
|
||||||
public void postConstruct() throws Exception {
|
public void postConstruct() {
|
||||||
this.initMethods.add("postConstruct");
|
this.initMethods.add("postConstruct");
|
||||||
}
|
}
|
||||||
|
|
||||||
@PreDestroy
|
@PreDestroy
|
||||||
public void preDestroy() throws Exception {
|
public void preDestroy() {
|
||||||
this.destroyMethods.add("preDestroy");
|
this.destroyMethods.add("preDestroy");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -274,13 +276,13 @@ class InitDestroyMethodLifecycleTests {
|
||||||
|
|
||||||
@PostConstruct
|
@PostConstruct
|
||||||
@Override
|
@Override
|
||||||
public void afterPropertiesSet() throws Exception {
|
public void afterPropertiesSet() {
|
||||||
this.initMethods.add("@PostConstruct.afterPropertiesSet");
|
this.initMethods.add("@PostConstruct.afterPropertiesSet");
|
||||||
}
|
}
|
||||||
|
|
||||||
@PreDestroy
|
@PreDestroy
|
||||||
@Override
|
@Override
|
||||||
public void destroy() throws Exception {
|
public void destroy() {
|
||||||
this.destroyMethods.add("@PreDestroy.destroy");
|
this.destroyMethods.add("@PreDestroy.destroy");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -292,18 +294,29 @@ class InitDestroyMethodLifecycleTests {
|
||||||
|
|
||||||
@PostConstruct
|
@PostConstruct
|
||||||
@Override
|
@Override
|
||||||
public void afterPropertiesSet() throws Exception {
|
public void afterPropertiesSet() {
|
||||||
this.initMethods.add("afterPropertiesSet");
|
this.initMethods.add("afterPropertiesSet");
|
||||||
}
|
}
|
||||||
|
|
||||||
@PreDestroy
|
@PreDestroy
|
||||||
@Override
|
@Override
|
||||||
public void destroy() throws Exception {
|
public void destroy() {
|
||||||
this.destroyMethods.add("destroy");
|
this.destroyMethods.add("destroy");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static class SubPackagePrivateInitDestroyBean extends PackagePrivateInitDestroyBean {
|
static class SubPackagePrivateInitDestroyBean extends PackagePrivateInitDestroyBean
|
||||||
|
implements InitializingBean, DisposableBean {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterPropertiesSet() {
|
||||||
|
this.initMethods.add("InitializingBean.afterPropertiesSet");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void destroy() {
|
||||||
|
this.destroyMethods.add("DisposableBean.destroy");
|
||||||
|
}
|
||||||
|
|
||||||
@PostConstruct
|
@PostConstruct
|
||||||
void postConstruct() {
|
void postConstruct() {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue