Skip to content

Commit bd72f1f

Browse files
committed
Fix inconsistencies in StaticListableBeanFactory
Closes gh-35119
1 parent 511739e commit bd72f1f

File tree

3 files changed

+47
-53
lines changed

3 files changed

+47
-53
lines changed

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

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2701,7 +2701,7 @@ public Object getOrderSource(Object obj) {
27012701
return null;
27022702
}
27032703
try {
2704-
RootBeanDefinition beanDefinition = (RootBeanDefinition) getMergedBeanDefinition(beanName);
2704+
BeanDefinition beanDefinition = getMergedBeanDefinition(beanName);
27052705
List<Object> sources = new ArrayList<>(3);
27062706
Object orderAttribute = beanDefinition.getAttribute(AbstractBeanDefinition.ORDER_ATTRIBUTE);
27072707
if (orderAttribute != null) {
@@ -2713,13 +2713,15 @@ public Object getOrderSource(Object obj) {
27132713
AbstractBeanDefinition.ORDER_ATTRIBUTE + "': " + orderAttribute.getClass().getName());
27142714
}
27152715
}
2716-
Method factoryMethod = beanDefinition.getResolvedFactoryMethod();
2717-
if (factoryMethod != null) {
2718-
sources.add(factoryMethod);
2719-
}
2720-
Class<?> targetType = beanDefinition.getTargetType();
2721-
if (targetType != null && targetType != obj.getClass()) {
2722-
sources.add(targetType);
2716+
if (beanDefinition instanceof RootBeanDefinition rootBeanDefinition) {
2717+
Method factoryMethod = rootBeanDefinition.getResolvedFactoryMethod();
2718+
if (factoryMethod != null) {
2719+
sources.add(factoryMethod);
2720+
}
2721+
Class<?> targetType = rootBeanDefinition.getTargetType();
2722+
if (targetType != null && targetType != obj.getClass()) {
2723+
sources.add(targetType);
2724+
}
27232725
}
27242726
return sources.toArray();
27252727
}

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

Lines changed: 23 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -113,15 +113,8 @@ public void addBean(String name, Object bean) {
113113
@Override
114114
public Object getBean(String name) throws BeansException {
115115
String beanName = BeanFactoryUtils.transformedBeanName(name);
116-
Object bean = this.beans.get(beanName);
116+
Object bean = obtainBean(beanName);
117117

118-
if (bean == null) {
119-
throw new NoSuchBeanDefinitionException(beanName,
120-
"Defined beans are [" + StringUtils.collectionToCommaDelimitedString(this.beans.keySet()) + "]");
121-
}
122-
123-
// Don't let calling code try to dereference the
124-
// bean factory if the bean isn't a factory
125118
if (BeanFactoryUtils.isFactoryDereference(name) && !(bean instanceof FactoryBean)) {
126119
throw new BeanIsNotAFactoryException(beanName, bean.getClass());
127120
}
@@ -162,6 +155,15 @@ public Object getBean(String name, Object... args) throws BeansException {
162155
return getBean(name);
163156
}
164157

158+
private Object obtainBean(String beanName) {
159+
Object bean = this.beans.get(beanName);
160+
if (bean == null) {
161+
throw new NoSuchBeanDefinitionException(beanName,
162+
"Defined beans are [" + StringUtils.collectionToCommaDelimitedString(this.beans.keySet()) + "]");
163+
}
164+
return bean;
165+
}
166+
165167
@Override
166168
public <T> T getBean(Class<T> requiredType) throws BeansException {
167169
String[] beanNames = getBeanNamesForType(requiredType);
@@ -202,20 +204,21 @@ public boolean containsBean(String name) {
202204

203205
@Override
204206
public boolean isSingleton(String name) throws NoSuchBeanDefinitionException {
205-
Object bean = getBean(name);
206-
// In case of FactoryBean, return singleton status of created object.
207-
if (bean instanceof FactoryBean<?> factoryBean) {
207+
String beanName = BeanFactoryUtils.transformedBeanName(name);
208+
Object bean = obtainBean(beanName);
209+
if (bean instanceof FactoryBean<?> factoryBean && !BeanFactoryUtils.isFactoryDereference(name)) {
208210
return factoryBean.isSingleton();
209211
}
210212
return true;
211213
}
212214

213215
@Override
214216
public boolean isPrototype(String name) throws NoSuchBeanDefinitionException {
215-
Object bean = getBean(name);
216-
// In case of FactoryBean, return prototype status of created object.
217-
return ((bean instanceof SmartFactoryBean<?> smartFactoryBean && smartFactoryBean.isPrototype()) ||
218-
(bean instanceof FactoryBean<?> factoryBean && !factoryBean.isSingleton()));
217+
String beanName = BeanFactoryUtils.transformedBeanName(name);
218+
Object bean = obtainBean(beanName);
219+
return (!BeanFactoryUtils.isFactoryDereference(name) &&
220+
((bean instanceof SmartFactoryBean<?> smartFactoryBean && smartFactoryBean.isPrototype()) ||
221+
(bean instanceof FactoryBean<?> factoryBean && !factoryBean.isSingleton())));
219222
}
220223

221224
@Override
@@ -240,15 +243,8 @@ public Class<?> getType(String name) throws NoSuchBeanDefinitionException {
240243
@Nullable
241244
public Class<?> getType(String name, boolean allowFactoryBeanInit) throws NoSuchBeanDefinitionException {
242245
String beanName = BeanFactoryUtils.transformedBeanName(name);
243-
244-
Object bean = this.beans.get(beanName);
245-
if (bean == null) {
246-
throw new NoSuchBeanDefinitionException(beanName,
247-
"Defined beans are [" + StringUtils.collectionToCommaDelimitedString(this.beans.keySet()) + "]");
248-
}
249-
246+
Object bean = obtainBean(beanName);
250247
if (bean instanceof FactoryBean<?> factoryBean && !BeanFactoryUtils.isFactoryDereference(name)) {
251-
// If it's a FactoryBean, we want to look at what it creates, not the factory class.
252248
return factoryBean.getObjectType();
253249
}
254250
return bean.getClass();
@@ -292,7 +288,7 @@ public <T> ObjectProvider<T> getBeanProvider(ResolvableType requiredType, boolea
292288
public T getObject() throws BeansException {
293289
String[] beanNames = getBeanNamesForType(requiredType);
294290
if (beanNames.length == 1) {
295-
return (T) getBean(beanNames[0], requiredType);
291+
return (T) getBean(beanNames[0]);
296292
}
297293
else if (beanNames.length > 1) {
298294
throw new NoUniqueBeanDefinitionException(requiredType, beanNames);
@@ -356,7 +352,7 @@ public String[] getBeanNamesForType(@Nullable ResolvableType type,
356352
boolean includeNonSingletons, boolean allowEagerInit) {
357353

358354
Class<?> resolved = (type != null ? type.resolve() : null);
359-
boolean isFactoryType = resolved != null && FactoryBean.class.isAssignableFrom(resolved);
355+
boolean isFactoryType = (resolved != null && FactoryBean.class.isAssignableFrom(resolved));
360356
List<String> matches = new ArrayList<>();
361357

362358
for (Map.Entry<String, Object> entry : this.beans.entrySet()) {
@@ -365,7 +361,7 @@ public String[] getBeanNamesForType(@Nullable ResolvableType type,
365361
if (beanInstance instanceof FactoryBean<?> factoryBean && !isFactoryType) {
366362
Class<?> objectType = factoryBean.getObjectType();
367363
if ((includeNonSingletons || factoryBean.isSingleton()) &&
368-
objectType != null && (type == null || type.isAssignableFrom(objectType))) {
364+
(type == null || (objectType != null && type.isAssignableFrom(objectType)))) {
369365
matches.add(beanName);
370366
}
371367
}
@@ -404,19 +400,15 @@ public <T> Map<String, T> getBeansOfType(@Nullable Class<T> type, boolean includ
404400
for (Map.Entry<String, Object> entry : this.beans.entrySet()) {
405401
String beanName = entry.getKey();
406402
Object beanInstance = entry.getValue();
407-
// Is bean a FactoryBean?
408403
if (beanInstance instanceof FactoryBean<?> factoryBean && !isFactoryType) {
409-
// Match object created by FactoryBean.
410404
Class<?> objectType = factoryBean.getObjectType();
411405
if ((includeNonSingletons || factoryBean.isSingleton()) &&
412-
objectType != null && (type == null || type.isAssignableFrom(objectType))) {
406+
(type == null || (objectType != null && type.isAssignableFrom(objectType)))) {
413407
matches.put(beanName, getBean(beanName, type));
414408
}
415409
}
416410
else {
417411
if (type == null || type.isInstance(beanInstance)) {
418-
// If type to match is FactoryBean, return FactoryBean itself.
419-
// Else, return bean instance.
420412
if (isFactoryType) {
421413
beanName = FACTORY_BEAN_PREFIX + beanName;
422414
}

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

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -388,33 +388,33 @@ void isSingletonAndIsPrototypeWithStaticFactory() {
388388

389389
assertThat(lbf.isSingleton("bean")).isTrue();
390390
assertThat(lbf.isSingleton("fb1")).isTrue();
391-
assertThat(lbf.isSingleton("fb2")).isTrue();
391+
assertThat(lbf.isSingleton("fb2")).isFalse();
392392
assertThat(lbf.isSingleton("sfb1")).isTrue();
393393
assertThat(lbf.isSingleton("sfb2")).isTrue();
394-
assertThat(lbf.isSingleton("sfb3")).isTrue();
395-
assertThat(lbf.isSingleton("sfb4")).isTrue();
394+
assertThat(lbf.isSingleton("sfb3")).isFalse();
395+
assertThat(lbf.isSingleton("sfb4")).isFalse();
396396

397397
assertThat(lbf.isSingleton("&fb1")).isTrue();
398-
assertThat(lbf.isSingleton("&fb2")).isFalse();
398+
assertThat(lbf.isSingleton("&fb2")).isTrue();
399399
assertThat(lbf.isSingleton("&sfb1")).isTrue();
400400
assertThat(lbf.isSingleton("&sfb2")).isTrue();
401-
assertThat(lbf.isSingleton("&sfb3")).isFalse();
402-
assertThat(lbf.isSingleton("&sfb4")).isFalse();
401+
assertThat(lbf.isSingleton("&sfb3")).isTrue();
402+
assertThat(lbf.isSingleton("&sfb4")).isTrue();
403403

404404
assertThat(lbf.isPrototype("bean")).isFalse();
405405
assertThat(lbf.isPrototype("fb1")).isFalse();
406-
assertThat(lbf.isPrototype("fb2")).isFalse();
407-
assertThat(lbf.isPrototype("sfb1")).isFalse();
406+
assertThat(lbf.isPrototype("fb2")).isTrue();
407+
assertThat(lbf.isPrototype("sfb1")).isTrue();
408408
assertThat(lbf.isPrototype("sfb2")).isFalse();
409-
assertThat(lbf.isPrototype("sfb3")).isFalse();
410-
assertThat(lbf.isPrototype("sfb4")).isFalse();
409+
assertThat(lbf.isPrototype("sfb3")).isTrue();
410+
assertThat(lbf.isPrototype("sfb4")).isTrue();
411411

412412
assertThat(lbf.isPrototype("&fb1")).isFalse();
413-
assertThat(lbf.isPrototype("&fb2")).isTrue();
414-
assertThat(lbf.isPrototype("&sfb1")).isTrue();
413+
assertThat(lbf.isPrototype("&fb2")).isFalse();
414+
assertThat(lbf.isPrototype("&sfb1")).isFalse();
415415
assertThat(lbf.isPrototype("&sfb2")).isFalse();
416-
assertThat(lbf.isPrototype("&sfb3")).isTrue();
417-
assertThat(lbf.isPrototype("&sfb4")).isTrue();
416+
assertThat(lbf.isPrototype("&sfb3")).isFalse();
417+
assertThat(lbf.isPrototype("&sfb4")).isFalse();
418418
}
419419

420420

0 commit comments

Comments
 (0)