Skip to content

Commit 8c44a61

Browse files
committed
Invalidate cache entries for matching types after singleton creation
Closes gh-35239
1 parent 5e338ef commit 8c44a61

File tree

2 files changed

+34
-4
lines changed

2 files changed

+34
-4
lines changed

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

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1455,11 +1455,18 @@ protected void checkForAliasCircle(String name, String alias) {
14551455
}
14561456
}
14571457

1458+
@Override
1459+
protected void addSingleton(String beanName, Object singletonObject) {
1460+
super.addSingleton(beanName, singletonObject);
1461+
Predicate<Class<?>> filter = (beanType -> beanType != Object.class && beanType.isInstance(singletonObject));
1462+
this.allBeanNamesByType.keySet().removeIf(filter);
1463+
this.singletonBeanNamesByType.keySet().removeIf(filter);
1464+
}
1465+
14581466
@Override
14591467
public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException {
14601468
super.registerSingleton(beanName, singletonObject);
14611469
updateManualSingletonNames(set -> set.add(beanName), set -> !this.beanDefinitionMap.containsKey(beanName));
1462-
clearByTypeCache();
14631470
}
14641471

14651472
@Override

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

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3202,6 +3202,29 @@ void nonPublicEnum() {
32023202
assertThat(holder.getNonPublicEnum()).isEqualTo(NonPublicEnum.VALUE_1);
32033203
}
32043204

3205+
@Test
3206+
void mostSpecificCacheEntryForTypeMatching() {
3207+
RootBeanDefinition bd1 = new RootBeanDefinition();
3208+
bd1.setFactoryBeanName("config");
3209+
bd1.setFactoryMethodName("create");
3210+
lbf.registerBeanDefinition("config", new RootBeanDefinition(BeanWithFactoryMethod.class));
3211+
lbf.registerBeanDefinition("bd1", bd1);
3212+
lbf.registerBeanDefinition("bd2", new RootBeanDefinition(NestedTestBean.class));
3213+
lbf.freezeConfiguration();
3214+
3215+
String[] allBeanNames = lbf.getBeanNamesForType(Object.class);
3216+
String[] nestedBeanNames = lbf.getBeanNamesForType(NestedTestBean.class);
3217+
assertThat(lbf.getType("bd1")).isEqualTo(TestBean.class);
3218+
assertThat(lbf.getBeanNamesForType(TestBean.class)).containsExactly("bd1");
3219+
assertThat(lbf.getBeanNamesForType(DerivedTestBean.class)).isEmpty();
3220+
lbf.getBean("bd1");
3221+
assertThat(lbf.getType("bd1")).isEqualTo(DerivedTestBean.class);
3222+
assertThat(lbf.getBeanNamesForType(TestBean.class)).containsExactly("bd1");
3223+
assertThat(lbf.getBeanNamesForType(DerivedTestBean.class)).containsExactly("bd1");
3224+
assertThat(lbf.getBeanNamesForType(NestedTestBean.class)).isSameAs(nestedBeanNames);
3225+
assertThat(lbf.getBeanNamesForType(Object.class)).isSameAs(allBeanNames);
3226+
}
3227+
32053228

32063229
private int registerBeanDefinitions(Properties p) {
32073230
return registerBeanDefinitions(p, null);
@@ -3418,7 +3441,7 @@ public void setName(String name) {
34183441
}
34193442

34203443
public TestBean create() {
3421-
TestBean tb = new TestBean();
3444+
DerivedTestBean tb = new DerivedTestBean();
34223445
tb.setName(this.name);
34233446
return tb;
34243447
}
@@ -3646,11 +3669,11 @@ private static class FactoryBeanDependentBean {
36463669

36473670
private FactoryBean<?> factoryBean;
36483671

3649-
public final FactoryBean<?> getFactoryBean() {
3672+
public FactoryBean<?> getFactoryBean() {
36503673
return this.factoryBean;
36513674
}
36523675

3653-
public final void setFactoryBean(final FactoryBean<?> factoryBean) {
3676+
public void setFactoryBean(FactoryBean<?> factoryBean) {
36543677
this.factoryBean = factoryBean;
36553678
}
36563679
}

0 commit comments

Comments
 (0)