Skip to content

Commit e7db15b

Browse files
committed
Perform type check before singleton check for early FactoryBean matching
Closes gh-34710
1 parent 8f9cbcd commit e7db15b

File tree

2 files changed

+33
-2
lines changed

2 files changed

+33
-2
lines changed

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

+7-2
Original file line numberDiff line numberDiff line change
@@ -639,10 +639,15 @@ private String[] doGetBeanNamesForType(ResolvableType type, boolean includeNonSi
639639
}
640640
}
641641
else {
642-
if (includeNonSingletons || isNonLazyDecorated ||
643-
(allowFactoryBeanInit && isSingleton(beanName, mbd, dbd))) {
642+
if (includeNonSingletons || isNonLazyDecorated) {
644643
matchFound = isTypeMatch(beanName, type, allowFactoryBeanInit);
645644
}
645+
else if (allowFactoryBeanInit) {
646+
// Type check before singleton check, avoiding FactoryBean instantiation
647+
// for early FactoryBean.isSingleton() calls on non-matching beans.
648+
matchFound = isTypeMatch(beanName, type, allowFactoryBeanInit) &&
649+
isSingleton(beanName, mbd, dbd);
650+
}
646651
if (!matchFound) {
647652
// In case of FactoryBean, try to match FactoryBean instance itself next.
648653
beanName = FACTORY_BEAN_PREFIX + beanName;

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

+26
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,32 @@ void nonInitializedFactoryBeanIgnoredByNonEagerTypeMatching() {
263263
assertThat(DummyFactory.wasPrototypeCreated()).as("prototype not instantiated").isFalse();
264264
}
265265

266+
@Test
267+
void nonInitializedFactoryBeanIgnoredByEagerTypeMatching() {
268+
RootBeanDefinition bd = new RootBeanDefinition(DummyFactory.class);
269+
bd.setAttribute(FactoryBean.OBJECT_TYPE_ATTRIBUTE, String.class);
270+
lbf.registerBeanDefinition("x1", bd);
271+
272+
assertBeanNamesForType(TestBean.class, false, true);
273+
assertThat(lbf.getBeanNamesForAnnotation(SuppressWarnings.class)).isEmpty();
274+
275+
assertThat(lbf.containsSingleton("x1")).isFalse();
276+
assertThat(lbf.containsBean("x1")).isTrue();
277+
assertThat(lbf.containsBean("&x1")).isTrue();
278+
assertThat(lbf.isSingleton("x1")).isTrue();
279+
assertThat(lbf.isSingleton("&x1")).isTrue();
280+
assertThat(lbf.isPrototype("x1")).isFalse();
281+
assertThat(lbf.isPrototype("&x1")).isFalse();
282+
assertThat(lbf.isTypeMatch("x1", TestBean.class)).isTrue();
283+
assertThat(lbf.isTypeMatch("&x1", TestBean.class)).isFalse();
284+
assertThat(lbf.isTypeMatch("&x1", DummyFactory.class)).isTrue();
285+
assertThat(lbf.isTypeMatch("&x1", ResolvableType.forClass(DummyFactory.class))).isTrue();
286+
assertThat(lbf.isTypeMatch("&x1", ResolvableType.forClassWithGenerics(FactoryBean.class, Object.class))).isTrue();
287+
assertThat(lbf.isTypeMatch("&x1", ResolvableType.forClassWithGenerics(FactoryBean.class, String.class))).isFalse();
288+
assertThat(lbf.getType("x1")).isEqualTo(TestBean.class);
289+
assertThat(lbf.getType("&x1")).isEqualTo(DummyFactory.class);
290+
}
291+
266292
@Test
267293
void initializedFactoryBeanFoundByNonEagerTypeMatching() {
268294
Properties p = new Properties();

0 commit comments

Comments
 (0)