diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java index b60b9f54632..81ce08d29ef 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java @@ -724,19 +724,18 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac int minNrOfArgs = (mbd.hasConstructorArgumentValues() ? mbd.getConstructorArgumentValues().getArgumentCount() : 0); Method[] candidates = ReflectionUtils.getUniqueDeclaredMethods(factoryClass); - for (Method factoryMethod : candidates) { - if (Modifier.isStatic(factoryMethod.getModifiers()) == isStatic && - factoryMethod.getName().equals(mbd.getFactoryMethodName()) && - factoryMethod.getParameterCount() >= minNrOfArgs) { + for (Method candidate : candidates) { + if (Modifier.isStatic(candidate.getModifiers()) == isStatic && mbd.isFactoryMethod(candidate) && + candidate.getParameterCount() >= minNrOfArgs) { // Declared type variables to inspect? - if (factoryMethod.getTypeParameters().length > 0) { + if (candidate.getTypeParameters().length > 0) { try { // Fully resolve parameter names and argument values. - Class[] paramTypes = factoryMethod.getParameterTypes(); + Class[] paramTypes = candidate.getParameterTypes(); String[] paramNames = null; ParameterNameDiscoverer pnd = getParameterNameDiscoverer(); if (pnd != null) { - paramNames = pnd.getParameterNames(factoryMethod); + paramNames = pnd.getParameterNames(candidate); } ConstructorArgumentValues cav = mbd.getConstructorArgumentValues(); Set usedValueHolders = new HashSet<>(paramTypes.length); @@ -753,9 +752,9 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac } } Class returnType = AutowireUtils.resolveReturnTypeForFactoryMethod( - factoryMethod, args, getBeanClassLoader()); - uniqueCandidate = (commonType == null && returnType == factoryMethod.getReturnType() ? - factoryMethod : null); + candidate, args, getBeanClassLoader()); + uniqueCandidate = (commonType == null && returnType == candidate.getReturnType() ? + candidate : null); commonType = ClassUtils.determineCommonAncestor(returnType, commonType); if (commonType == null) { // Ambiguous return types found: return null to indicate "not determinable". @@ -769,8 +768,8 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac } } else { - uniqueCandidate = (commonType == null ? factoryMethod : null); - commonType = ClassUtils.determineCommonAncestor(factoryMethod.getReturnType(), commonType); + uniqueCandidate = (commonType == null ? candidate : null); + commonType = ClassUtils.determineCommonAncestor(candidate.getReturnType(), commonType); if (commonType == null) { // Ambiguous return types found: return null to indicate "not determinable". return null; diff --git a/spring-context/src/test/java/org/springframework/context/annotation/ConfigurationClassPostProcessorTests.java b/spring-context/src/test/java/org/springframework/context/annotation/ConfigurationClassPostProcessorTests.java index 19f96e8caf0..5aa861ae752 100644 --- a/spring-context/src/test/java/org/springframework/context/annotation/ConfigurationClassPostProcessorTests.java +++ b/spring-context/src/test/java/org/springframework/context/annotation/ConfigurationClassPostProcessorTests.java @@ -22,6 +22,7 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import java.util.Arrays; import java.util.List; +import java.util.Map; import javax.annotation.PostConstruct; import org.junit.Before; @@ -809,6 +810,15 @@ public class ConfigurationClassPostProcessorTests { assertSame(ctx.getBean(TestBean.class), bean.testBeans.get(0)); } + @Test + public void testMapInjectionFromSameConfigurationClass() { + ApplicationContext ctx = new AnnotationConfigApplicationContext(MapInjectionConfiguration.class); + MapInjectionConfiguration bean = ctx.getBean(MapInjectionConfiguration.class); + assertNotNull(bean.testBeans); + assertEquals(1, bean.testBeans.size()); + assertSame(ctx.getBean(Runnable.class), bean.testBeans.get("testBean")); + } + @Test public void testBeanLookupFromSameConfigurationClass() { ApplicationContext ctx = new AnnotationConfigApplicationContext(BeanLookupConfiguration.class); @@ -1566,6 +1576,23 @@ public class ConfigurationClassPostProcessorTests { } } + @Configuration + public static class MapInjectionConfiguration { + + @Autowired + private Map testBeans; + + @Bean + Runnable testBean() { + return () -> {}; + } + + // Unrelated, not to be considered as a factory method + private boolean testBean(boolean param) { + return param; + } + } + @Configuration static abstract class BeanLookupConfiguration {