1

I want to create two bean implementing the same interface. Beans have names, but when I use @Qualifier annotation

got error like:

Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'cdPlayer' defined in soundsystem.CDPlayerConfig: Unsatisfied dependency expressed through method 'cdPlayer' parameter 0: No qualifying bean of type [soundsystem.CompactDisc] is defined: expected single matching bean but found 2: sss,aaa; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [soundsystem.CompactDisc] is defined: expected single matching bean but found 2: sss,aaa

This is my configuration class.

@Configuration
public class CDPlayerConfig {

@Bean(name="bbb")
public CompactDisc blankDisc(){
    List<String> list = new LinkedList<>();
    list.add("qwer");
    list.add("qazw");
    return new BlankDisc("one", "two", list);
}

@Bean(name="aaa")
public CompactDisc sgtPeppers(){
    return null;
}
@Bean
public MediaPlayer cdPlayer(CompactDisc cd){
    return new CDPlayer(cd);
}
}

This is my test class.

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes=CDPlayerConfig.class)
public class CDPlayerTest {

@Rule
public final SystemOutRule log = new SystemOutRule().enableLog();

@Autowired
private MediaPlayer player;

@Autowired
@Qualifier("aaa")
private CompactDisc cd;

@Test
public void cdShouldNotBeNull(){
    assertNotNull(cd);
}


@Test
public void play(){
    player.play();
    assertEquals("XYZ", log.getLogWithNormalizedLineSeparator());
}
}

Edit: My CDPlayer class

public class CDPlayer implements MediaPlayer {

private CompactDisc cd;

@Autowired  
public CDPlayer(CompactDisc cd){
    this.cd = cd;
}
@Override
public void play() {
    // TODO Auto-generated method stub
    cd.play();
}
}
lassa
  • 173
  • 9

2 Answers2

3

Change your code to the following:

@Bean
public MediaPlayer cdPlayer(@Qualifier("bbb") CompactDisc cd){
    return new CDPlayer(cd);
}
ck1
  • 5,243
  • 1
  • 21
  • 25
  • Still doesn't work. When I use @Primary annotation it works, but i want to choose by name. I added CDPlayer class code – lassa Jun 28 '16 at 13:41
0

spring tries to inject a bean Compactdisc here:

@Bean
public MediaPlayer cdPlayer(CompactDisc cd){
    return new CDPlayer(cd);
}

You have to add the @Qualifier Annotation to CompactDisc.

An other way is to remove the parameter from CDplayer constructor and put it as a parameter to the play method

Jens
  • 67,715
  • 15
  • 98
  • 113
  • Still doesn't work. When I use @Primary annotation it works, but i want to choose by name. I added CDPlayer class code – lassa Jun 28 '16 at 13:44
  • Remove the Parameter from CDplayer constructor and put it as a Parameter to the Play method – Jens Jun 28 '16 at 13:49