简体   繁体   中英

right way to inject multiple implementation using spring

I have a class A which has a field ADep (A's Dependency). Now aDep has two types of implementations say typeA impls and typeB impls . I want to use typeB when a particular exception is thrown when using typeA . I am using spring for dependency injection.

I can think of 3 ways :

  1. I define one more field aDep and inject any typeB implementation on it (See class below). Problem with this is anyone can initialize this field with any typeA implementations and my assumption on this field is the behavior of typeB .
class A {
    ADep aDepI1;//only typeA impls
    ADep aDepI2;//only typeB impls
}
  1. A has only one field and I use spring's bean factory to get typeB impl inside my class if the exception is thrown when using typeA .

  2. I create 2 instances of A using spring, one with typeA and one with typeB and the users of A has to use the typeA first and if an exception is thrown call again with typeB instance.

I think the 3rd solution would be the best. What are your thoughts, any help is appreciated?

In Java 8 and above you could do something like

public interface IMyInterface{}

public class ClassA implements IMyInterface{}

public class ClassB implements IMyInterface{}

Then you could do something like this (please notice this code is not a copy/paste just take the idea)

public class SomeClient{
    @Autowired List<IMyInterface> myInterfaceImps;

   public IMyInterface obtainImplementation(Some inputData)
   {
    return myInterfaceImps.stream().filter(c->somePredicate(c,inputData))
    .findFirst()
    .orElse(defineHereDefaulBehaviour());
   }

 }

Then using some like that you could autowired SomeClient class to retrieve the needed imp

Another way is to make it by @Qualifiers and ServiceLocatorFactoryBean

I just would like to add that it looks like you are using exceptions as if statements, and it's a code smell. The solution that I'm sharing is about how to retrieve different beans depending on some condition defined into predicate function, or else if depending on "something" you could retrieve the bean itself by ServiceLocator. Depending on how you implement is, I should work, but your code should use exception as ifs.

Regards

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