Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Resolving Spring conflict with @Autowired and @Qualifier

I have an interface

public interface ParentService{}

And Two Implementation Class

@Service("child1service")    
public class Child1 implements ParentService{}

@Service("child2service")
public class Child2 implements ParentService{}

Now my Controller

public class ServeChild1Controller extendds AbstractController{

 @Autowired
 public ServeChild1Controller(@Qualifier("child1service") ParentService child1service){
 super(child1service)
  } 

Similarly there is ServeChild2Controller..

So when i run I get the following error

Error for ServeChild1Controller: No unique bean of type [com.service.ParentService] is defined: expected single matching bean but found 2 child1service, child2service

Am trying to read more about these Annotations but not able to resolve it .. Any pointers will be of help Thanks

like image 623
harshit Avatar asked Oct 21 '11 18:10

harshit


2 Answers

In order to use a specific instance you need to provide Annotate the service with @Qualifier(id) and in the constructor anotate the parameter with @Qualifier again, as follows:

@Service("child1service")
@Qualifier("child1service")
public class Child1 implements ParentService{}

@Service("child2service")
@Qualifier("child2service")
public class Child2 implements ParentService{}

And you constructor:

public class ServeChild1Controller extendds AbstractController{

    @Autowired
    public ServeChild1Controller(@Qualifier("child1service") ParentService child1service){
        super(child1service)
    }

}
like image 179
Francisco Spaeth Avatar answered Sep 18 '22 13:09

Francisco Spaeth


With Spring (beans) 4.3 it works exactly the way you wrote it in your question.

I can give you example with implementation groupping that I faced recently. Spring can autowire based on on type and qualifier distinction. Using service names is not enough as they need to be unique so you would end up with type conflict.

Example:

public interface ServiceA {}
public interface ServiceB {}

@Qualifier("mockedA")    
@Service
public class MockedA implements ServiceA {}

@Qualifier("realA")
@Service
public class RealA implements ServiceA {}

@Qualifier("mockedB")    
@Service
public class MockedB implements ServiceB {}

@Qualifier("realB")
@Service
public class RealB implements ServiceB {}

@Autowired
public ABController (
    @Qualifier("mockedA") ServiceA mockedA,
    @Qualifier("realA") ServiceA realA,
    @Qualifier("mockedB") ServiceB mockedB,
    @Qualifier("realB") ServiceB realB) {
} 
like image 33
zeratul021 Avatar answered Sep 21 '22 13:09

zeratul021