Browse Source

Invalidate cache entries for matching types after singleton creation

Closes gh-35239
pull/35405/head
Juergen Hoeller 5 months ago
parent
commit
8c44a61033
  1. 9
      spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java
  2. 29
      spring-beans/src/test/java/org/springframework/beans/factory/DefaultListableBeanFactoryTests.java

9
spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java

@ -1455,11 +1455,18 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto @@ -1455,11 +1455,18 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
}
}
@Override
protected void addSingleton(String beanName, Object singletonObject) {
super.addSingleton(beanName, singletonObject);
Predicate<Class<?>> 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

29
spring-beans/src/test/java/org/springframework/beans/factory/DefaultListableBeanFactoryTests.java

@ -3202,6 +3202,29 @@ class DefaultListableBeanFactoryTests { @@ -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 { @@ -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 { @@ -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;
}
}

Loading…
Cancel
Save