3

I have two spring bean classes which are implemeting the same interface.

 public interface Abc()
  {
    String getNumber();
  }

The two classes are

 @Service
 public class SomeClass implements abc
  {

  @Override
  public class getNumber()
  {


  }

 }


 @Service
 public class SomeClass1 implements abc
 {

  @Override
  public class getNumber()
  {

  }
  }

In my Service class.

 @Service
 public class Demo
  {

  @Autowired
  private Abc abc;

  }

  }

I got an error "required a single bean, but 2 were found"

For that error i can have the chance to put @Primary in the top of one of the bean.

But i have only way to say "one bean configuration" based on the value which i will get in runtime(From the database).

Can you please suggest me a way.

Andronicus
  • 25,419
  • 17
  • 47
  • 88
madhuri
  • 103
  • 2
  • 11
  • 1
    https://stackoverflow.com/questions/40830548/spring-autowired-and-qualifier – R.G Apr 12 '19 at 09:45
  • I don't fully understand the question, but there's a `@Qualifier` annotation for dealing with multiple spring bean implementations. – NeplatnyUdaj Apr 12 '19 at 09:45
  • The question is unclear about what you want want. However, if you are looking for to have beans based on external property then you can use @ConditionalOnProperty. Check more on Spring Docs for use case. – Rana_S Apr 12 '19 at 11:42

3 Answers3

6

You can autowire a list of interfaces and then choose the right one. You can write:

@Autowired
List<Abc> abcs;

this will result in a list of implementations of the interface. In your method body you can then choose the right one.

Andronicus
  • 25,419
  • 17
  • 47
  • 88
3

Couple of ways you can autowire the correct implementation.

Change your autowired field name to the same name of the implementation class (in camelcase)

@Autowired
private Abc someClass;

This will attempt to find an implementation of interface 'Abc' with the classname 'SomeClass'.

Another way is to add a bean name to your service annotation

@Service("someClass")
public class SomeClass implements abc

This can then be autowired like the following

@Autowired
@Qualifier("someClass")
private Abc SomeClass;
  • Are you sure sping autowires interfaces the way you described in the first option? What if a have SomeClass1 and SomeClass2? – Dedyshka May 08 '20 at 15:29
1

I think the problem he is asking about how to configure two implentation and also using the right bean dynamically(based on data in DB) . It seems this is the an example for factory pattern

Psuedo Code

Class SomeFactory{
 @Autowired
 private Abc someClass;
  @Autowired
  private Abc someClass1;// keeping bean Name same as class name would solve bean finding issue

public Abc getBeanFor(String type) {
if("someClass".equals(type)
    return someClass;
  return someClass1;
} 
}

Class TestClass{
 @Autowired
   private SomeFactory factory ;
  private void someProcess() {
   // Read type from DB for data

   factory.getBeanFor(typeReadFromData)
                .process();
 } 
} 
Shirishkumar Bari
  • 2,692
  • 1
  • 28
  • 36