From fd159ad0821362ace61903be91ba897b24c6343a Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Tue, 11 Jun 2019 20:56:30 +0200 Subject: [PATCH] Custom init/destroy methods get invoked through interface is possible Closes gh-22939 --- .../AbstractAutowireCapableBeanFactory.java | 7 ++++--- .../factory/support/DisposableBeanAdapter.java | 16 +++++++++------- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java index fe10c1654b09..caa76ad26037 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java @@ -1860,7 +1860,7 @@ protected void invokeCustomInitMethod(String beanName, final Object bean, RootBe String initMethodName = mbd.getInitMethodName(); Assert.state(initMethodName != null, "No init method set"); - final Method initMethod = (mbd.isNonPublicAccessAllowed() ? + Method initMethod = (mbd.isNonPublicAccessAllowed() ? BeanUtils.findMethod(bean.getClass(), initMethodName) : ClassUtils.getMethodIfAvailable(bean.getClass(), initMethodName)); @@ -1882,15 +1882,16 @@ protected void invokeCustomInitMethod(String beanName, final Object bean, RootBe if (logger.isTraceEnabled()) { logger.trace("Invoking init method '" + initMethodName + "' on bean with name '" + beanName + "'"); } + Method methodToInvoke = ClassUtils.getInterfaceMethodIfPossible(initMethod); if (System.getSecurityManager() != null) { AccessController.doPrivileged((PrivilegedAction) () -> { - ReflectionUtils.makeAccessible(initMethod); + ReflectionUtils.makeAccessible(methodToInvoke); return null; }); try { AccessController.doPrivileged((PrivilegedExceptionAction) () -> - initMethod.invoke(bean), getAccessControlContext()); + methodToInvoke.invoke(bean), getAccessControlContext()); } catch (PrivilegedActionException pae) { InvocationTargetException ex = (InvocationTargetException) pae.getException(); diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/DisposableBeanAdapter.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/DisposableBeanAdapter.java index e8fc4ce2d7cb..9d1ce3466cb0 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/DisposableBeanAdapter.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/DisposableBeanAdapter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 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. @@ -112,15 +112,15 @@ public DisposableBeanAdapter(Object bean, String beanName, RootBeanDefinition be if (destroyMethodName != null && !(this.invokeDisposableBean && "destroy".equals(destroyMethodName)) && !beanDefinition.isExternallyManagedDestroyMethod(destroyMethodName)) { this.destroyMethodName = destroyMethodName; - this.destroyMethod = determineDestroyMethod(destroyMethodName); - if (this.destroyMethod == null) { + Method destroyMethod = determineDestroyMethod(destroyMethodName); + if (destroyMethod == null) { if (beanDefinition.isEnforceDestroyMethod()) { throw new BeanDefinitionValidationException("Could not find a destroy method named '" + destroyMethodName + "' on bean with name '" + beanName + "'"); } } else { - Class[] paramTypes = this.destroyMethod.getParameterTypes(); + Class[] paramTypes = destroyMethod.getParameterTypes(); if (paramTypes.length > 1) { throw new BeanDefinitionValidationException("Method '" + destroyMethodName + "' of bean '" + beanName + "' has more than one parameter - not supported as destroy method"); @@ -129,7 +129,9 @@ else if (paramTypes.length == 1 && boolean.class != paramTypes[0]) { throw new BeanDefinitionValidationException("Method '" + destroyMethodName + "' of bean '" + beanName + "' has a non-boolean parameter - not supported as destroy method"); } + destroyMethod = ClassUtils.getInterfaceMethodIfPossible(destroyMethod); } + this.destroyMethod = destroyMethod; } this.beanPostProcessors = filterPostProcessors(postProcessors, bean); } @@ -271,9 +273,9 @@ public void destroy() { invokeCustomDestroyMethod(this.destroyMethod); } else if (this.destroyMethodName != null) { - Method methodToCall = determineDestroyMethod(this.destroyMethodName); - if (methodToCall != null) { - invokeCustomDestroyMethod(methodToCall); + Method methodToInvoke = determineDestroyMethod(this.destroyMethodName); + if (methodToInvoke != null) { + invokeCustomDestroyMethod(ClassUtils.getInterfaceMethodIfPossible(methodToInvoke)); } } }