Uploaded image for project: 'Spring Framework'
  1. Spring Framework
  2. SPR-7854

@Primary and primary attribute of <bean> element are not considered for calls to getBean(Class)

    Details

    • Type: Improvement
    • Status: Resolved
    • Priority: Major
    • Resolution: Complete
    • Affects Version/s: 3.0.5
    • Fix Version/s: 3.2.1
    • Component/s: Core
    • Labels:
      None
    • Last commented by a User:
      true

      Description

      If a bean is annotated with @Primary or the attribute primary is set on the <bean> element, then the injection mechanism choose the primary configured bean as first choice if more than one candidate are qualified. This works fine with usage of @Autowired or @Inject.

      By resolve the bean over the application context, I expected the same behaviour. Because the DefaultListableBeanFactory implementation of <T> T getBean(Class<T> requiredType) method doesn't check the the primary attribute of BeanDefinition, a NoSuchBeanDefinitionException is thrown in case of multiple qualified bean candidates regardless the the primary qualification.

      I posted a workaround solution in my blog: http://develop.nydi.ch/2010/12/spring-primary-bean-injection/

      To reproduce this behavior you can run the following JUnit test case.

      @RunWith(SpringJUnit4ClassRunner.class)
      @ContextConfiguration(locations = { TestSupport.SPRING_CONFIG_FILE_PATH })
      public class PrimarySupportTest implements ApplicationContextAware {
      
      	private SingleService singleService;
      	private ApplicationContext applicationContext;
      	
      	@Inject
          public void setSingleService(SingleService singleService) {
      		this.singleService = singleService;
      	}
      	
      	@Override
      	public void setApplicationContext(ApplicationContext applicationContext)
      			throws BeansException {
      		this.applicationContext = applicationContext;
      	}
          
          @Test
          public void testInjectedService() {
              Assert.assertNotNull("contextSingleService is null", singleService);
              Assert.assertEquals("wrong instance", SingleServiceImpl_1.class.getName(), singleService.getClass().getName());
          }
          
          @Test
          public void testServiceWithGetBean() {
          	SingleService contextSingleService = applicationContext.getBean("singleServiceImpl_1", SingleService.class);
              Assert.assertNotNull("contextSingleService is null", contextSingleService);
              Assert.assertEquals("wrong instance", SingleServiceImpl_1.class.getName(), contextSingleService.getClass().getName());
      
          	contextSingleService = applicationContext.getBean("singleServiceImpl_2", SingleService.class);
              Assert.assertNotNull("contextSingleService is null", contextSingleService);
              Assert.assertEquals("wrong instance", SingleServiceImpl_2.class.getName(), contextSingleService.getClass().getName());
      
              // SingleServiceImpl_1 is annotated with @Primary so SingleServiceImpl_1 instance should returned here, but 
          	contextSingleService = applicationContext.getBean(SingleService.class);
              Assert.assertNotNull("contextSingleService is null", contextSingleService);
              Assert.assertEquals("wrong instance", SingleServiceImpl_1.class.getName(), contextSingleService.getClass().getName());
          }
      }
      
      public interface BaseService {
      	void callBase();
      }
      
      @Service
      @Named
      @Primary
      public class SingleServiceImpl_1 implements SingleService {
      	@Override
      	public void callMe() {
      	}
      }
      
      @Service
      @Named
      public class SingleServiceImpl_2 implements SingleService {
      	@Override
      	public void callMe() {
      	}
      }
      

        Attachments

          Issue Links

            Activity

              People

              • Assignee:
                pwebb Phil Webb
                Reporter:
                nydi Daniel Nydegger
                Last updater:
                Nick Williams
              • Votes:
                12 Vote for this issue
                Watchers:
                13 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved:
                  Days since last comment:
                  5 years, 39 weeks, 4 days ago