Browse Source

Don't consider singleton instances when deducing bean class

Update `RegisteredBean` bean class detection to not consider
singletons. Prior to this commit, any beans that had been instantiated
could return the wrong class, especially if they were implemented using
a lambda.

See gh-28414
pull/28427/head
Phillip Webb 3 years ago
parent
commit
7700570253
  1. 7
      spring-beans/src/main/java/org/springframework/beans/factory/support/RegisteredBean.java
  2. 20
      spring-beans/src/test/java/org/springframework/beans/factory/support/RegisteredBeanTests.java

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

@ -158,9 +158,6 @@ public final class RegisteredBean { @@ -158,9 +158,6 @@ public final class RegisteredBean {
* @return the bean class
*/
public Class<?> getBeanClass() {
if (this.beanFactory.containsSingleton(getBeanName())) {
return this.beanFactory.getSingleton(getBeanName()).getClass();
}
return ClassUtils.getUserClass(getBeanType().toClass());
}
@ -169,10 +166,6 @@ public final class RegisteredBean { @@ -169,10 +166,6 @@ public final class RegisteredBean {
* @return the bean type
*/
public ResolvableType getBeanType() {
if (this.beanFactory.containsSingleton(getBeanName())) {
return ResolvableType
.forInstance(this.beanFactory.getSingleton(getBeanName()));
}
return getMergedBeanDefinition().getResolvableType();
}

20
spring-beans/src/test/java/org/springframework/beans/factory/support/RegisteredBeanTests.java

@ -21,6 +21,7 @@ import org.junit.jupiter.api.Test; @@ -21,6 +21,7 @@ import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
@ -112,12 +113,6 @@ class RegisteredBeanTests { @@ -112,12 +113,6 @@ class RegisteredBeanTests {
assertThat(registeredBean.getBeanClass()).isEqualTo(TestBean.class);
}
@Test
void getBeanClassWhenSingletonReturnsBeanClass() {
RegisteredBean registeredBean = RegisteredBean.of(this.beanFactory, "sb");
assertThat(registeredBean.getBeanClass()).isEqualTo(TestBean.class);
}
@Test
void getBeanTypeReturnsBeanType() {
RegisteredBean registeredBean = RegisteredBean.of(this.beanFactory, "bd");
@ -125,9 +120,16 @@ class RegisteredBeanTests { @@ -125,9 +120,16 @@ class RegisteredBeanTests {
}
@Test
void getBeanTypeWhenSingletonReturnsBeanType() {
RegisteredBean registeredBean = RegisteredBean.of(this.beanFactory, "sb");
assertThat(registeredBean.getBeanType().toClass()).isEqualTo(TestBean.class);
void getBeanTypeWhenHasInstanceBackedByLambdaDoesNotReturnLambdaType() {
this.beanFactory.registerBeanDefinition("bfpp", new RootBeanDefinition(
BeanFactoryPostProcessor.class, RegisteredBeanTests::getBeanFactoryPostProcessorLambda));
this.beanFactory.getBean("bfpp");
RegisteredBean registeredBean = RegisteredBean.of(this.beanFactory, "bfpp");
assertThat(registeredBean.getBeanType().toClass()).isEqualTo(BeanFactoryPostProcessor.class);
}
static BeanFactoryPostProcessor getBeanFactoryPostProcessorLambda() {
return bf -> {};
}
@Test

Loading…
Cancel
Save