Merge branch '5.3.x'
# Conflicts: # spring-beans/src/main/java/org/springframework/beans/factory/annotation/InitDestroyAnnotationBeanPostProcessor.java # spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java # spring-beans/src/main/java/org/springframework/beans/factory/support/DisposableBeanAdapter.java # spring-context/src/test/java/org/springframework/context/annotation/Spr3775InitDestroyLifecycleTests.java
This commit is contained in:
commit
466dd825ac
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
@ -302,7 +302,7 @@ public class InitDestroyAnnotationBeanPostProcessor
|
|||
beanDefinition.registerExternallyManagedInitMethod(methodIdentifier);
|
||||
checkedInitMethods.add(element);
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Registered init method on class [" + this.targetClass.getName() + "]: " + element);
|
||||
logger.trace("Registered init method on class [" + this.targetClass.getName() + "]: " + methodIdentifier);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -313,7 +313,7 @@ public class InitDestroyAnnotationBeanPostProcessor
|
|||
beanDefinition.registerExternallyManagedDestroyMethod(methodIdentifier);
|
||||
checkedDestroyMethods.add(element);
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Registered destroy method on class [" + this.targetClass.getName() + "]: " + element);
|
||||
logger.trace("Registered destroy method on class [" + this.targetClass.getName() + "]: " + methodIdentifier);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1780,7 +1780,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
|||
throws Throwable {
|
||||
|
||||
boolean isInitializingBean = (bean instanceof InitializingBean);
|
||||
if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
|
||||
if (isInitializingBean && (mbd == null || !mbd.hasAnyExternallyManagedInitMethod("afterPropertiesSet"))) {
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
|
||||
}
|
||||
|
|
@ -1793,7 +1793,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
|||
for (String initMethodName : initMethodNames) {
|
||||
if (StringUtils.hasLength(initMethodName) &&
|
||||
!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
|
||||
!mbd.isExternallyManagedInitMethod(initMethodName)) {
|
||||
!mbd.hasAnyExternallyManagedInitMethod(initMethodName)) {
|
||||
invokeCustomInitMethod(beanName, bean, mbd, initMethodName);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ import org.springframework.util.StringUtils;
|
|||
* @author Juergen Hoeller
|
||||
* @author Costin Leau
|
||||
* @author Stephane Nicoll
|
||||
* @author Sam Brannen
|
||||
* @since 2.0
|
||||
* @see AbstractBeanFactory
|
||||
* @see org.springframework.beans.factory.DisposableBean
|
||||
|
|
@ -102,12 +103,12 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
|
|||
this.beanName = beanName;
|
||||
this.nonPublicAccessAllowed = beanDefinition.isNonPublicAccessAllowed();
|
||||
this.invokeDisposableBean = (bean instanceof DisposableBean &&
|
||||
!beanDefinition.isExternallyManagedDestroyMethod(DESTROY_METHOD_NAME));
|
||||
!beanDefinition.hasAnyExternallyManagedDestroyMethod(DESTROY_METHOD_NAME));
|
||||
|
||||
String[] destroyMethodNames = inferDestroyMethodsIfNecessary(bean, beanDefinition);
|
||||
if (!ObjectUtils.isEmpty(destroyMethodNames) &&
|
||||
!(this.invokeDisposableBean && DESTROY_METHOD_NAME.equals(destroyMethodNames[0])) &&
|
||||
!beanDefinition.isExternallyManagedDestroyMethod(destroyMethodNames[0])) {
|
||||
!beanDefinition.hasAnyExternallyManagedDestroyMethod(destroyMethodNames[0])) {
|
||||
|
||||
this.invokeAutoCloseable =
|
||||
(bean instanceof AutoCloseable && CLOSE_METHOD_NAME.equals(destroyMethodNames[0]));
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
@ -49,6 +49,7 @@ import org.springframework.util.Assert;
|
|||
*
|
||||
* @author Rod Johnson
|
||||
* @author Juergen Hoeller
|
||||
* @author Sam Brannen
|
||||
* @see GenericBeanDefinition
|
||||
* @see ChildBeanDefinition
|
||||
*/
|
||||
|
|
@ -436,7 +437,7 @@ public class RootBeanDefinition extends AbstractBeanDefinition {
|
|||
}
|
||||
|
||||
/**
|
||||
* Check whether the given method or field is an externally managed configuration member.
|
||||
* Determine if the given method or field is an externally managed configuration member.
|
||||
*/
|
||||
public boolean isExternallyManagedConfigMember(Member configMember) {
|
||||
synchronized (this.postProcessingLock) {
|
||||
|
|
@ -446,7 +447,7 @@ public class RootBeanDefinition extends AbstractBeanDefinition {
|
|||
}
|
||||
|
||||
/**
|
||||
* Return all externally managed configuration methods and fields (as an immutable Set).
|
||||
* Get all externally managed configuration methods and fields (as an immutable Set).
|
||||
* @since 5.3.11
|
||||
*/
|
||||
public Set<Member> getExternallyManagedConfigMembers() {
|
||||
|
|
@ -458,7 +459,15 @@ public class RootBeanDefinition extends AbstractBeanDefinition {
|
|||
}
|
||||
|
||||
/**
|
||||
* Register an externally managed configuration initialization method.
|
||||
* Register an externally managed configuration initialization method —
|
||||
* for example, a method annotated with JSR-250's
|
||||
* {@link javax.annotation.PostConstruct} annotation.
|
||||
* <p>The supplied {@code initMethod} may be the
|
||||
* {@linkplain Method#getName() simple method name} for non-private methods or the
|
||||
* {@linkplain org.springframework.util.ClassUtils#getQualifiedMethodName(Method)
|
||||
* qualified method name} for {@code private} methods. A qualified name is
|
||||
* necessary for {@code private} methods in order to disambiguate between
|
||||
* multiple private methods with the same name within a class hierarchy.
|
||||
*/
|
||||
public void registerExternallyManagedInitMethod(String initMethod) {
|
||||
synchronized (this.postProcessingLock) {
|
||||
|
|
@ -470,7 +479,10 @@ public class RootBeanDefinition extends AbstractBeanDefinition {
|
|||
}
|
||||
|
||||
/**
|
||||
* Check whether the given method name indicates an externally managed initialization method.
|
||||
* Determine if the given method name indicates an externally managed
|
||||
* initialization method.
|
||||
* <p>See {@link #registerExternallyManagedInitMethod} for details
|
||||
* regarding the format for the supplied {@code initMethod}.
|
||||
*/
|
||||
public boolean isExternallyManagedInitMethod(String initMethod) {
|
||||
synchronized (this.postProcessingLock) {
|
||||
|
|
@ -479,8 +491,40 @@ public class RootBeanDefinition extends AbstractBeanDefinition {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the given method name indicates an externally managed
|
||||
* initialization method, regardless of method visibility.
|
||||
* <p>In contrast to {@link #isExternallyManagedInitMethod(String)}, this
|
||||
* method also returns {@code true} if there is a {@code private} externally
|
||||
* managed initialization method that has been
|
||||
* {@linkplain #registerExternallyManagedInitMethod(String) registered}
|
||||
* using a qualified method name instead of a simple method name.
|
||||
* @since 5.3.17
|
||||
*/
|
||||
boolean hasAnyExternallyManagedInitMethod(String initMethod) {
|
||||
synchronized (this.postProcessingLock) {
|
||||
if (isExternallyManagedInitMethod(initMethod)) {
|
||||
return true;
|
||||
}
|
||||
if (this.externallyManagedInitMethods != null) {
|
||||
for (String candidate : this.externallyManagedInitMethods) {
|
||||
int indexOfDot = candidate.lastIndexOf(".");
|
||||
if (indexOfDot >= 0) {
|
||||
String methodName = candidate.substring(indexOfDot + 1);
|
||||
if (methodName.equals(initMethod)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all externally managed initialization methods (as an immutable Set).
|
||||
* <p>See {@link #registerExternallyManagedInitMethod} for details
|
||||
* regarding the format for the initialization methods in the returned set.
|
||||
* @since 5.3.11
|
||||
*/
|
||||
public Set<String> getExternallyManagedInitMethods() {
|
||||
|
|
@ -492,7 +536,15 @@ public class RootBeanDefinition extends AbstractBeanDefinition {
|
|||
}
|
||||
|
||||
/**
|
||||
* Register an externally managed configuration destruction method.
|
||||
* Register an externally managed configuration destruction method —
|
||||
* for example, a method annotated with JSR-250's
|
||||
* {@link javax.annotation.PreDestroy} annotation.
|
||||
* <p>The supplied {@code destroyMethod} may be the
|
||||
* {@linkplain Method#getName() simple method name} for non-private methods or the
|
||||
* {@linkplain org.springframework.util.ClassUtils#getQualifiedMethodName(Method)
|
||||
* qualified method name} for {@code private} methods. A qualified name is
|
||||
* necessary for {@code private} methods in order to disambiguate between
|
||||
* multiple private methods with the same name within a class hierarchy.
|
||||
*/
|
||||
public void registerExternallyManagedDestroyMethod(String destroyMethod) {
|
||||
synchronized (this.postProcessingLock) {
|
||||
|
|
@ -504,7 +556,10 @@ public class RootBeanDefinition extends AbstractBeanDefinition {
|
|||
}
|
||||
|
||||
/**
|
||||
* Check whether the given method name indicates an externally managed destruction method.
|
||||
* Determine if the given method name indicates an externally managed
|
||||
* destruction method.
|
||||
* <p>See {@link #registerExternallyManagedDestroyMethod} for details
|
||||
* regarding the format for the supplied {@code destroyMethod}.
|
||||
*/
|
||||
public boolean isExternallyManagedDestroyMethod(String destroyMethod) {
|
||||
synchronized (this.postProcessingLock) {
|
||||
|
|
@ -514,7 +569,39 @@ public class RootBeanDefinition extends AbstractBeanDefinition {
|
|||
}
|
||||
|
||||
/**
|
||||
* Return all externally managed destruction methods (as an immutable Set).
|
||||
* Determine if the given method name indicates an externally managed
|
||||
* destruction method, regardless of method visibility.
|
||||
* <p>In contrast to {@link #isExternallyManagedDestroyMethod(String)}, this
|
||||
* method also returns {@code true} if there is a {@code private} externally
|
||||
* managed destruction method that has been
|
||||
* {@linkplain #registerExternallyManagedDestroyMethod(String) registered}
|
||||
* using a qualified method name instead of a simple method name.
|
||||
* @since 5.3.17
|
||||
*/
|
||||
boolean hasAnyExternallyManagedDestroyMethod(String destroyMethod) {
|
||||
synchronized (this.postProcessingLock) {
|
||||
if (isExternallyManagedDestroyMethod(destroyMethod)) {
|
||||
return true;
|
||||
}
|
||||
if (this.externallyManagedDestroyMethods != null) {
|
||||
for (String candidate : this.externallyManagedDestroyMethods) {
|
||||
int indexOfDot = candidate.lastIndexOf(".");
|
||||
if (indexOfDot >= 0) {
|
||||
String methodName = candidate.substring(indexOfDot + 1);
|
||||
if (methodName.equals(destroyMethod)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all externally managed destruction methods (as an immutable Set).
|
||||
* <p>See {@link #registerExternallyManagedDestroyMethod} for details
|
||||
* regarding the format for the destruction methods in the returned set.
|
||||
* @since 5.3.11
|
||||
*/
|
||||
public Set<String> getExternallyManagedDestroyMethods() {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,279 @@
|
|||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.context.annotation;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.annotation.PreDestroy;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests which verify expected <em>init</em> and <em>destroy</em> bean lifecycle
|
||||
* behavior as requested in
|
||||
* <a href="https://github.com/spring-projects/spring-framework/issues/8455" target="_blank">SPR-3775</a>.
|
||||
*
|
||||
* <p>Specifically, combinations of the following are tested:
|
||||
* <ul>
|
||||
* <li>{@link InitializingBean} & {@link DisposableBean} interfaces</li>
|
||||
* <li>Custom {@link RootBeanDefinition#getInitMethodName() init} &
|
||||
* {@link RootBeanDefinition#getDestroyMethodName() destroy} methods</li>
|
||||
* <li>JSR 250's {@link javax.annotation.PostConstruct @PostConstruct} &
|
||||
* {@link javax.annotation.PreDestroy @PreDestroy} annotations</li>
|
||||
* </ul>
|
||||
*
|
||||
* @author Sam Brannen
|
||||
* @since 2.5
|
||||
*/
|
||||
class InitDestroyMethodLifecycleTests {
|
||||
|
||||
@Test
|
||||
void initDestroyMethods() {
|
||||
Class<?> beanClass = InitDestroyBean.class;
|
||||
DefaultListableBeanFactory beanFactory = createBeanFactoryAndRegisterBean(beanClass, "afterPropertiesSet", "destroy");
|
||||
InitDestroyBean bean = beanFactory.getBean(InitDestroyBean.class);
|
||||
assertThat(bean.initMethods).as("init-methods").containsExactly("afterPropertiesSet");
|
||||
beanFactory.destroySingletons();
|
||||
assertThat(bean.destroyMethods).as("destroy-methods").containsExactly("destroy");
|
||||
}
|
||||
|
||||
@Test
|
||||
void initializingDisposableInterfaces() {
|
||||
Class<?> beanClass = CustomInitializingDisposableBean.class;
|
||||
DefaultListableBeanFactory beanFactory = createBeanFactoryAndRegisterBean(beanClass, "customInit", "customDestroy");
|
||||
CustomInitializingDisposableBean bean = beanFactory.getBean(CustomInitializingDisposableBean.class);
|
||||
assertThat(bean.initMethods).as("init-methods").containsExactly("afterPropertiesSet", "customInit");
|
||||
beanFactory.destroySingletons();
|
||||
assertThat(bean.destroyMethods).as("destroy-methods").containsExactly("destroy", "customDestroy");
|
||||
}
|
||||
|
||||
@Test
|
||||
void initializingDisposableInterfacesWithShadowedMethods() {
|
||||
Class<?> beanClass = InitializingDisposableWithShadowedMethodsBean.class;
|
||||
DefaultListableBeanFactory beanFactory = createBeanFactoryAndRegisterBean(beanClass, "afterPropertiesSet", "destroy");
|
||||
InitializingDisposableWithShadowedMethodsBean bean = beanFactory.getBean(InitializingDisposableWithShadowedMethodsBean.class);
|
||||
assertThat(bean.initMethods).as("init-methods").containsExactly("InitializingBean.afterPropertiesSet");
|
||||
beanFactory.destroySingletons();
|
||||
assertThat(bean.destroyMethods).as("destroy-methods").containsExactly("DisposableBean.destroy");
|
||||
}
|
||||
|
||||
@Test
|
||||
void jsr250Annotations() {
|
||||
Class<?> beanClass = CustomAnnotatedInitDestroyBean.class;
|
||||
DefaultListableBeanFactory beanFactory = createBeanFactoryAndRegisterBean(beanClass, "customInit", "customDestroy");
|
||||
CustomAnnotatedInitDestroyBean bean = beanFactory.getBean(CustomAnnotatedInitDestroyBean.class);
|
||||
assertThat(bean.initMethods).as("init-methods").containsExactly("postConstruct", "afterPropertiesSet", "customInit");
|
||||
beanFactory.destroySingletons();
|
||||
assertThat(bean.destroyMethods).as("destroy-methods").containsExactly("preDestroy", "destroy", "customDestroy");
|
||||
}
|
||||
|
||||
@Test
|
||||
void jsr250AnnotationsWithShadowedMethods() {
|
||||
Class<?> beanClass = CustomAnnotatedInitDestroyWithShadowedMethodsBean.class;
|
||||
DefaultListableBeanFactory beanFactory = createBeanFactoryAndRegisterBean(beanClass, "customInit", "customDestroy");
|
||||
CustomAnnotatedInitDestroyWithShadowedMethodsBean bean = beanFactory.getBean(CustomAnnotatedInitDestroyWithShadowedMethodsBean.class);
|
||||
assertThat(bean.initMethods).as("init-methods").containsExactly("@PostConstruct.afterPropertiesSet", "customInit");
|
||||
beanFactory.destroySingletons();
|
||||
assertThat(bean.destroyMethods).as("destroy-methods").containsExactly("@PreDestroy.destroy", "customDestroy");
|
||||
}
|
||||
|
||||
@Test
|
||||
void jsr250AnnotationsWithCustomPrivateInitDestroyMethods() {
|
||||
Class<?> beanClass = CustomAnnotatedPrivateInitDestroyBean.class;
|
||||
DefaultListableBeanFactory beanFactory = createBeanFactoryAndRegisterBean(beanClass, "customInit1", "customDestroy1");
|
||||
CustomAnnotatedPrivateInitDestroyBean bean = beanFactory.getBean(CustomAnnotatedPrivateInitDestroyBean.class);
|
||||
assertThat(bean.initMethods).as("init-methods").containsExactly("@PostConstruct.privateCustomInit1", "afterPropertiesSet");
|
||||
beanFactory.destroySingletons();
|
||||
assertThat(bean.destroyMethods).as("destroy-methods").containsExactly("@PreDestroy.privateCustomDestroy1", "destroy");
|
||||
}
|
||||
|
||||
@Test
|
||||
void jsr250AnnotationsWithCustomSameMethodNames() {
|
||||
Class<?> beanClass = CustomAnnotatedPrivateSameNameInitDestroyBean.class;
|
||||
DefaultListableBeanFactory beanFactory = createBeanFactoryAndRegisterBean(beanClass, "customInit1", "customDestroy1");
|
||||
CustomAnnotatedPrivateSameNameInitDestroyBean bean = beanFactory.getBean(CustomAnnotatedPrivateSameNameInitDestroyBean.class);
|
||||
assertThat(bean.initMethods).as("init-methods").containsExactly("@PostConstruct.privateCustomInit1", "@PostConstruct.sameNameCustomInit1", "afterPropertiesSet");
|
||||
beanFactory.destroySingletons();
|
||||
assertThat(bean.destroyMethods).as("destroy-methods").containsExactly("@PreDestroy.sameNameCustomDestroy1", "@PreDestroy.privateCustomDestroy1", "destroy");
|
||||
}
|
||||
|
||||
@Test
|
||||
void allLifecycleMechanismsAtOnce() {
|
||||
Class<?> beanClass = AllInOneBean.class;
|
||||
DefaultListableBeanFactory beanFactory = createBeanFactoryAndRegisterBean(beanClass, "afterPropertiesSet", "destroy");
|
||||
AllInOneBean bean = beanFactory.getBean(AllInOneBean.class);
|
||||
assertThat(bean.initMethods).as("init-methods").containsExactly("afterPropertiesSet");
|
||||
beanFactory.destroySingletons();
|
||||
assertThat(bean.destroyMethods).as("destroy-methods").containsExactly("destroy");
|
||||
}
|
||||
|
||||
|
||||
private static DefaultListableBeanFactory createBeanFactoryAndRegisterBean(Class<?> beanClass,
|
||||
String initMethodName, String destroyMethodName) {
|
||||
|
||||
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
|
||||
RootBeanDefinition beanDefinition = new RootBeanDefinition(beanClass);
|
||||
beanDefinition.setInitMethodName(initMethodName);
|
||||
beanDefinition.setDestroyMethodName(destroyMethodName);
|
||||
beanFactory.addBeanPostProcessor(new CommonAnnotationBeanPostProcessor());
|
||||
beanFactory.registerBeanDefinition("lifecycleTestBean", beanDefinition);
|
||||
return beanFactory;
|
||||
}
|
||||
|
||||
|
||||
static class InitDestroyBean {
|
||||
|
||||
final List<String> initMethods = new ArrayList<>();
|
||||
final List<String> destroyMethods = new ArrayList<>();
|
||||
|
||||
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
this.initMethods.add("afterPropertiesSet");
|
||||
}
|
||||
|
||||
public void destroy() throws Exception {
|
||||
this.destroyMethods.add("destroy");
|
||||
}
|
||||
}
|
||||
|
||||
static class InitializingDisposableWithShadowedMethodsBean extends InitDestroyBean implements
|
||||
InitializingBean, DisposableBean {
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
this.initMethods.add("InitializingBean.afterPropertiesSet");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() throws Exception {
|
||||
this.destroyMethods.add("DisposableBean.destroy");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static class CustomInitDestroyBean {
|
||||
|
||||
final List<String> initMethods = new ArrayList<>();
|
||||
final List<String> destroyMethods = new ArrayList<>();
|
||||
|
||||
public void customInit() throws Exception {
|
||||
this.initMethods.add("customInit");
|
||||
}
|
||||
|
||||
public void customDestroy() throws Exception {
|
||||
this.destroyMethods.add("customDestroy");
|
||||
}
|
||||
}
|
||||
|
||||
static class CustomAnnotatedPrivateInitDestroyBean extends CustomInitializingDisposableBean {
|
||||
|
||||
@PostConstruct
|
||||
private void customInit1() throws Exception {
|
||||
this.initMethods.add("@PostConstruct.privateCustomInit1");
|
||||
}
|
||||
|
||||
@PreDestroy
|
||||
private void customDestroy1() throws Exception {
|
||||
this.destroyMethods.add("@PreDestroy.privateCustomDestroy1");
|
||||
}
|
||||
}
|
||||
|
||||
static class CustomAnnotatedPrivateSameNameInitDestroyBean extends CustomAnnotatedPrivateInitDestroyBean {
|
||||
|
||||
@PostConstruct
|
||||
@SuppressWarnings("unused")
|
||||
private void customInit1() throws Exception {
|
||||
this.initMethods.add("@PostConstruct.sameNameCustomInit1");
|
||||
}
|
||||
|
||||
@PreDestroy
|
||||
@SuppressWarnings("unused")
|
||||
private void customDestroy1() throws Exception {
|
||||
this.destroyMethods.add("@PreDestroy.sameNameCustomDestroy1");
|
||||
}
|
||||
}
|
||||
|
||||
static class CustomInitializingDisposableBean extends CustomInitDestroyBean
|
||||
implements InitializingBean, DisposableBean {
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
this.initMethods.add("afterPropertiesSet");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() throws Exception {
|
||||
this.destroyMethods.add("destroy");
|
||||
}
|
||||
}
|
||||
|
||||
static class CustomAnnotatedInitDestroyBean extends CustomInitializingDisposableBean {
|
||||
|
||||
@PostConstruct
|
||||
public void postConstruct() throws Exception {
|
||||
this.initMethods.add("postConstruct");
|
||||
}
|
||||
|
||||
@PreDestroy
|
||||
public void preDestroy() throws Exception {
|
||||
this.destroyMethods.add("preDestroy");
|
||||
}
|
||||
}
|
||||
|
||||
static class CustomAnnotatedInitDestroyWithShadowedMethodsBean extends CustomInitializingDisposableBean {
|
||||
|
||||
@PostConstruct
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
this.initMethods.add("@PostConstruct.afterPropertiesSet");
|
||||
}
|
||||
|
||||
@PreDestroy
|
||||
@Override
|
||||
public void destroy() throws Exception {
|
||||
this.destroyMethods.add("@PreDestroy.destroy");
|
||||
}
|
||||
}
|
||||
|
||||
static class AllInOneBean implements InitializingBean, DisposableBean {
|
||||
|
||||
final List<String> initMethods = new ArrayList<>();
|
||||
final List<String> destroyMethods = new ArrayList<>();
|
||||
|
||||
@PostConstruct
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
this.initMethods.add("afterPropertiesSet");
|
||||
}
|
||||
|
||||
@PreDestroy
|
||||
@Override
|
||||
public void destroy() throws Exception {
|
||||
this.destroyMethods.add("destroy");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue