简体   繁体   中英

Injecting spring bean among two beans- implementing same interface

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.

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.

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;

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();
 } 
} 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM