From 3c3e07e324e54d1175d59d6284646b363cd56f5d Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Sat, 1 Nov 2014 23:03:02 +0100 Subject: [PATCH] Defensive handling of manually registered singleton names (based on Spring Integration test failure) Issue: SPR-12404 --- .../support/DefaultListableBeanFactory.java | 9 +++++-- ...PathFactoryBeanDefinitionScannerTests.java | 24 ++++++++++++------- 2 files changed, 23 insertions(+), 10 deletions(-) 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 93e646070f..e93cdd37cb 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 @@ -469,8 +469,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto // Check manually registered singletons too. for (String beanName : this.manualSingletonNames) { - // Only check if manually registered. - if (!containsBeanDefinition(beanName)) { + try { // In case of FactoryBean, match object created by FactoryBean. if (isFactoryBean(beanName)) { if ((includeNonSingletons || isSingleton(beanName)) && isTypeMatch(beanName, type)) { @@ -486,6 +485,12 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto result.add(beanName); } } + catch (NoSuchBeanDefinitionException ex) { + // Shouldn't happen - probably a result of circular reference resolution... + if (logger.isDebugEnabled()) { + logger.debug("Failed to check manually registered singleton with name '" + beanName + "'", ex); + } + } } return StringUtils.toStringArray(result); diff --git a/spring-context/src/test/java/org/springframework/context/annotation/ClassPathFactoryBeanDefinitionScannerTests.java b/spring-context/src/test/java/org/springframework/context/annotation/ClassPathFactoryBeanDefinitionScannerTests.java index bbea00f17b..e92fba2898 100644 --- a/spring-context/src/test/java/org/springframework/context/annotation/ClassPathFactoryBeanDefinitionScannerTests.java +++ b/spring-context/src/test/java/org/springframework/context/annotation/ClassPathFactoryBeanDefinitionScannerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2014 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,7 +16,7 @@ package org.springframework.context.annotation; -import junit.framework.TestCase; +import org.junit.Test; import org.springframework.aop.scope.ScopedObject; import org.springframework.aop.support.AopUtils; @@ -25,20 +25,24 @@ import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.support.RootBeanDefinition; import org.springframework.context.annotation4.DependencyBean; import org.springframework.context.annotation4.FactoryMethodComponent; +import org.springframework.context.support.AbstractApplicationContext; import org.springframework.context.support.GenericApplicationContext; import org.springframework.tests.context.SimpleMapScope; import org.springframework.tests.sample.beans.TestBean; import org.springframework.util.ClassUtils; +import static org.junit.Assert.*; + /** * @author Mark Pollack * @author Juergen Hoeller */ -public class ClassPathFactoryBeanDefinitionScannerTests extends TestCase { +public class ClassPathFactoryBeanDefinitionScannerTests { private static final String BASE_PACKAGE = FactoryMethodComponent.class.getPackage().getName(); + @Test public void testSingletonScopedFactoryMethod() { GenericApplicationContext context = new GenericApplicationContext(); ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(context); @@ -52,13 +56,13 @@ public class ClassPathFactoryBeanDefinitionScannerTests extends TestCase { FactoryMethodComponent fmc = context.getBean("factoryMethodComponent", FactoryMethodComponent.class); assertFalse(fmc.getClass().getName().contains(ClassUtils.CGLIB_CLASS_SEPARATOR)); - TestBean tb = (TestBean)context.getBean("publicInstance"); //2 + TestBean tb = (TestBean) context.getBean("publicInstance"); //2 assertEquals("publicInstance", tb.getName()); - TestBean tb2 = (TestBean)context.getBean("publicInstance"); //2 + TestBean tb2 = (TestBean) context.getBean("publicInstance"); //2 assertEquals("publicInstance", tb2.getName()); assertSame(tb2, tb); - tb = (TestBean)context.getBean("protectedInstance"); //3 + tb = (TestBean) context.getBean("protectedInstance"); //3 assertEquals("protectedInstance", tb.getName()); assertSame(tb, context.getBean("protectedInstance")); assertEquals("0", tb.getCountry()); @@ -78,8 +82,9 @@ public class ClassPathFactoryBeanDefinitionScannerTests extends TestCase { assertTrue(bean instanceof ScopedObject); QualifiedClientBean clientBean = context.getBean("clientBean", QualifiedClientBean.class); - assertSame(clientBean.testBean, context.getBean("publicInstance")); - assertSame(clientBean.dependencyBean, context.getBean("dependencyBean")); + assertSame(context.getBean("publicInstance"), clientBean.testBean); + assertSame(context.getBean("dependencyBean"), clientBean.dependencyBean); + assertSame(context, clientBean.applicationContext); } @@ -90,6 +95,9 @@ public class ClassPathFactoryBeanDefinitionScannerTests extends TestCase { @Autowired public DependencyBean dependencyBean; + + @Autowired + AbstractApplicationContext applicationContext; } }