BeanFactory prefers local primary bean to primary bean in parent factory (SPR-5871)

This commit is contained in:
Juergen Hoeller 2009-09-08 23:01:26 +00:00
parent ee1c68ead4
commit 634d4b4d4c
2 changed files with 34 additions and 9 deletions

View File

@ -808,10 +808,19 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
Object beanInstance = entry.getValue();
if (isPrimary(candidateBeanName, beanInstance)) {
if (primaryBeanName != null) {
throw new NoSuchBeanDefinitionException(descriptor.getDependencyType(),
"more than one 'primary' bean found among candidates: " + candidateBeans.keySet());
boolean candidateLocal = containsBeanDefinition(candidateBeanName);
boolean primaryLocal = containsBeanDefinition(primaryBeanName);
if (candidateLocal == primaryLocal) {
throw new NoSuchBeanDefinitionException(descriptor.getDependencyType(),
"more than one 'primary' bean found among candidates: " + candidateBeans.keySet());
}
else if (candidateLocal && !primaryLocal) {
primaryBeanName = candidateBeanName;
}
}
else {
primaryBeanName = candidateBeanName;
}
primaryBeanName = candidateBeanName;
}
if (primaryBeanName == null &&
(this.resolvableDependencies.values().contains(beanInstance) ||

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2008 the original author or authors.
* Copyright 2002-2009 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,18 +16,16 @@
package org.springframework.beans.factory.xml;
import junit.framework.TestCase;
import junit.framework.Assert;
import junit.framework.TestCase;
import test.beans.TestBean;
import org.springframework.beans.factory.config.PropertiesFactoryBean;
import org.springframework.beans.factory.config.RuntimeBeanReference;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.core.io.ClassPathResource;
import test.beans.TestBean;
/**
* @author Rob Harrop
* @author Juergen Hoeller
@ -69,7 +67,7 @@ public class AutowireWithExclusionTests extends TestCase {
public void testByTypeAutowireWithPrimaryInParentFactory() throws Exception {
CountingFactory.reset();
XmlBeanFactory parent = getBeanFactory("autowire-with-exclusion.xml");
((AbstractBeanDefinition) parent.getBeanDefinition("props1")).setPrimary(true);
parent.getBeanDefinition("props1").setPrimary(true);
parent.preInstantiateSingletons();
DefaultListableBeanFactory child = new DefaultListableBeanFactory(parent);
RootBeanDefinition robDef = new RootBeanDefinition(TestBean.class, RootBeanDefinition.AUTOWIRE_BY_TYPE);
@ -100,6 +98,24 @@ public class AutowireWithExclusionTests extends TestCase {
Assert.assertEquals(1, CountingFactory.getFactoryBeanInstanceCount());
}
public void testByTypeAutowireWithPrimaryInParentAndChild() throws Exception {
CountingFactory.reset();
XmlBeanFactory parent = getBeanFactory("autowire-with-exclusion.xml");
parent.getBeanDefinition("props1").setPrimary(true);
parent.preInstantiateSingletons();
DefaultListableBeanFactory child = new DefaultListableBeanFactory(parent);
RootBeanDefinition robDef = new RootBeanDefinition(TestBean.class, RootBeanDefinition.AUTOWIRE_BY_TYPE);
robDef.getPropertyValues().addPropertyValue("spouse", new RuntimeBeanReference("sally"));
child.registerBeanDefinition("rob2", robDef);
RootBeanDefinition propsDef = new RootBeanDefinition(PropertiesFactoryBean.class);
propsDef.getPropertyValues().addPropertyValue("properties", "name=props3");
propsDef.setPrimary(true);
child.registerBeanDefinition("props3", propsDef);
TestBean rob = (TestBean) child.getBean("rob2");
assertEquals("props3", rob.getSomeProperties().getProperty("name"));
Assert.assertEquals(1, CountingFactory.getFactoryBeanInstanceCount());
}
public void testByTypeAutowireWithInclusion() throws Exception {
CountingFactory.reset();
XmlBeanFactory beanFactory = getBeanFactory("autowire-with-inclusion.xml");