0

In Spring, is it possible to avoid a NoUniqueBeanDefinitionException in the following scenario:

  • My application references beans in a 3rd party library

     appBean="thirdPartyClass"
    
  • The bean code is in a 3rd party library I can't edit

     @Component
     public class ThirdPartyClass {
    
         @Autowired
         private ThirdPartyInterface thirdPartyInterface;
    
  • The third party interface is used by two classes I do control

This class:

  public class MyClass1 implements ThirdPartyInterface {

and this class:

   public class MyClass2 implements ThirdPartyInterface {

Currently, NoUniqueBeanDefinitionException is occurring when I try to start my application saying the following:

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'thirdPartyClass': Unsatisfied dependency expressed through field 'thirdPartyIntereface'; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'ThirdPartyInterface' available: expected single matching bean but found 2: MyClass1,MyClass2

user7340
  • 256
  • 1
  • 10

2 Answers2

2

Considering you cannot change the ThirdPartyClass class.

Make one of the implemented classes as @Primary to be considered as the primary bean to be Autowired in the ThirdPartyClass class.

@Primary
@Component
public class MyClass1 implements ThirdPartyInterface {
}

And add @Qualifier to the other implemented class. And use that same qualifier in your other classes to Autowire and use it seamlessly.

@Component
@Qualifier("queue2")
public class MyClass2 implements ThirdPartyInterface {
}

@Component
public class MyOtherClass {
     @Autowired
     @Qualifier("queue2")
     private ThirdPartyInterface thirdPartyInterface;
}
sas
  • 512
  • 2
  • 8
0

The error clearly says what the problem is -

When you have 2 class implementing same interface and you are trying to use @Autowired via the interface, Spring does not know which implementation to pick (MyClass1 or MyClass2).

You need to be specific. Use @Qualifier to specify which implementation to pick.

I quickly found one example here - Spring @Autowired and @Qualifier

Vivek Vardhan
  • 1,118
  • 3
  • 21
  • 44
  • I can't change the third party class where the @Autowired is. – user7340 Jun 29 '21 at 02:53
  • @user7340 Then you can use the approach that @sas suggested. You will have to create another version of `ThirdPartyClass` to use other implementation. Else, only Primary will be picked. – Vivek Vardhan Jun 29 '21 at 06:31