diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java index 4173274a394..cbe60f9a525 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java @@ -1455,11 +1455,18 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto } } + @Override + protected void addSingleton(String beanName, Object singletonObject) { + super.addSingleton(beanName, singletonObject); + Predicate> filter = (beanType -> beanType != Object.class && beanType.isInstance(singletonObject)); + this.allBeanNamesByType.keySet().removeIf(filter); + this.singletonBeanNamesByType.keySet().removeIf(filter); + } + @Override public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException { super.registerSingleton(beanName, singletonObject); updateManualSingletonNames(set -> set.add(beanName), set -> !this.beanDefinitionMap.containsKey(beanName)); - clearByTypeCache(); } @Override diff --git a/spring-beans/src/test/java/org/springframework/beans/factory/DefaultListableBeanFactoryTests.java b/spring-beans/src/test/java/org/springframework/beans/factory/DefaultListableBeanFactoryTests.java index b05c53d87a0..dc964ad5ff4 100644 --- a/spring-beans/src/test/java/org/springframework/beans/factory/DefaultListableBeanFactoryTests.java +++ b/spring-beans/src/test/java/org/springframework/beans/factory/DefaultListableBeanFactoryTests.java @@ -3202,6 +3202,29 @@ class DefaultListableBeanFactoryTests { assertThat(holder.getNonPublicEnum()).isEqualTo(NonPublicEnum.VALUE_1); } + @Test + void mostSpecificCacheEntryForTypeMatching() { + RootBeanDefinition bd1 = new RootBeanDefinition(); + bd1.setFactoryBeanName("config"); + bd1.setFactoryMethodName("create"); + lbf.registerBeanDefinition("config", new RootBeanDefinition(BeanWithFactoryMethod.class)); + lbf.registerBeanDefinition("bd1", bd1); + lbf.registerBeanDefinition("bd2", new RootBeanDefinition(NestedTestBean.class)); + lbf.freezeConfiguration(); + + String[] allBeanNames = lbf.getBeanNamesForType(Object.class); + String[] nestedBeanNames = lbf.getBeanNamesForType(NestedTestBean.class); + assertThat(lbf.getType("bd1")).isEqualTo(TestBean.class); + assertThat(lbf.getBeanNamesForType(TestBean.class)).containsExactly("bd1"); + assertThat(lbf.getBeanNamesForType(DerivedTestBean.class)).isEmpty(); + lbf.getBean("bd1"); + assertThat(lbf.getType("bd1")).isEqualTo(DerivedTestBean.class); + assertThat(lbf.getBeanNamesForType(TestBean.class)).containsExactly("bd1"); + assertThat(lbf.getBeanNamesForType(DerivedTestBean.class)).containsExactly("bd1"); + assertThat(lbf.getBeanNamesForType(NestedTestBean.class)).isSameAs(nestedBeanNames); + assertThat(lbf.getBeanNamesForType(Object.class)).isSameAs(allBeanNames); + } + private int registerBeanDefinitions(Properties p) { return registerBeanDefinitions(p, null); @@ -3418,7 +3441,7 @@ class DefaultListableBeanFactoryTests { } public TestBean create() { - TestBean tb = new TestBean(); + DerivedTestBean tb = new DerivedTestBean(); tb.setName(this.name); return tb; } @@ -3646,11 +3669,11 @@ class DefaultListableBeanFactoryTests { private FactoryBean factoryBean; - public final FactoryBean getFactoryBean() { + public FactoryBean getFactoryBean() { return this.factoryBean; } - public final void setFactoryBean(final FactoryBean factoryBean) { + public void setFactoryBean(FactoryBean factoryBean) { this.factoryBean = factoryBean; } }