Injecting service class by interface?










0















So I have 2 Service classes that implement the same interface:



@Service
public class ServiceOne implements InterfaceOne



@Service
public class ServiceTwo implements InterfaceOne




I was wondering how I can inject particular instance inside the controller ?



@RestController
@RequestMapping("/test")
public class MyController
@Inject
public MyController(InterfaceOne service)





I'm not sure how DI is supposed to work with service classes. Basically those two services classes have the same interface and I was hoping to avoid nessesary if's if I could just inject the right one into the controller. An example would be much appreciated.



Edit: Sorry guys, I wasn't clear. What I also need to figure out is, which service class needs to be injected in the controller without specifying concrete implementation at that point. So, I was hoping there is a way to do some kind of if statement and check which implementation of the service should be plugged in.










share|improve this question



















  • 4





    Hello, in this case, I think you should use @Qualifier on your services.

    – Mickael
    Nov 14 '18 at 10:22











  • You can give them names: stackoverflow.com/questions/48941960/…

    – Thilo
    Nov 14 '18 at 10:22











  • I think that either you will use @Qualifier as suggested by Mickael or you will @Autowire the specific service instead of autowiring the interface.

    – Christos K.
    Nov 14 '18 at 10:26











  • Sorry guys, I wasn't clear at first. I have updated the description

    – Zed
    Nov 14 '18 at 10:27















0















So I have 2 Service classes that implement the same interface:



@Service
public class ServiceOne implements InterfaceOne



@Service
public class ServiceTwo implements InterfaceOne




I was wondering how I can inject particular instance inside the controller ?



@RestController
@RequestMapping("/test")
public class MyController
@Inject
public MyController(InterfaceOne service)





I'm not sure how DI is supposed to work with service classes. Basically those two services classes have the same interface and I was hoping to avoid nessesary if's if I could just inject the right one into the controller. An example would be much appreciated.



Edit: Sorry guys, I wasn't clear. What I also need to figure out is, which service class needs to be injected in the controller without specifying concrete implementation at that point. So, I was hoping there is a way to do some kind of if statement and check which implementation of the service should be plugged in.










share|improve this question



















  • 4





    Hello, in this case, I think you should use @Qualifier on your services.

    – Mickael
    Nov 14 '18 at 10:22











  • You can give them names: stackoverflow.com/questions/48941960/…

    – Thilo
    Nov 14 '18 at 10:22











  • I think that either you will use @Qualifier as suggested by Mickael or you will @Autowire the specific service instead of autowiring the interface.

    – Christos K.
    Nov 14 '18 at 10:26











  • Sorry guys, I wasn't clear at first. I have updated the description

    – Zed
    Nov 14 '18 at 10:27













0












0








0








So I have 2 Service classes that implement the same interface:



@Service
public class ServiceOne implements InterfaceOne



@Service
public class ServiceTwo implements InterfaceOne




I was wondering how I can inject particular instance inside the controller ?



@RestController
@RequestMapping("/test")
public class MyController
@Inject
public MyController(InterfaceOne service)





I'm not sure how DI is supposed to work with service classes. Basically those two services classes have the same interface and I was hoping to avoid nessesary if's if I could just inject the right one into the controller. An example would be much appreciated.



Edit: Sorry guys, I wasn't clear. What I also need to figure out is, which service class needs to be injected in the controller without specifying concrete implementation at that point. So, I was hoping there is a way to do some kind of if statement and check which implementation of the service should be plugged in.










share|improve this question
















So I have 2 Service classes that implement the same interface:



@Service
public class ServiceOne implements InterfaceOne



@Service
public class ServiceTwo implements InterfaceOne




I was wondering how I can inject particular instance inside the controller ?



@RestController
@RequestMapping("/test")
public class MyController
@Inject
public MyController(InterfaceOne service)





I'm not sure how DI is supposed to work with service classes. Basically those two services classes have the same interface and I was hoping to avoid nessesary if's if I could just inject the right one into the controller. An example would be much appreciated.



Edit: Sorry guys, I wasn't clear. What I also need to figure out is, which service class needs to be injected in the controller without specifying concrete implementation at that point. So, I was hoping there is a way to do some kind of if statement and check which implementation of the service should be plugged in.







java spring-boot






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 14 '18 at 10:26







Zed

















asked Nov 14 '18 at 10:20









ZedZed

1,99952755




1,99952755







  • 4





    Hello, in this case, I think you should use @Qualifier on your services.

    – Mickael
    Nov 14 '18 at 10:22











  • You can give them names: stackoverflow.com/questions/48941960/…

    – Thilo
    Nov 14 '18 at 10:22











  • I think that either you will use @Qualifier as suggested by Mickael or you will @Autowire the specific service instead of autowiring the interface.

    – Christos K.
    Nov 14 '18 at 10:26











  • Sorry guys, I wasn't clear at first. I have updated the description

    – Zed
    Nov 14 '18 at 10:27












  • 4





    Hello, in this case, I think you should use @Qualifier on your services.

    – Mickael
    Nov 14 '18 at 10:22











  • You can give them names: stackoverflow.com/questions/48941960/…

    – Thilo
    Nov 14 '18 at 10:22











  • I think that either you will use @Qualifier as suggested by Mickael or you will @Autowire the specific service instead of autowiring the interface.

    – Christos K.
    Nov 14 '18 at 10:26











  • Sorry guys, I wasn't clear at first. I have updated the description

    – Zed
    Nov 14 '18 at 10:27







4




4





Hello, in this case, I think you should use @Qualifier on your services.

– Mickael
Nov 14 '18 at 10:22





Hello, in this case, I think you should use @Qualifier on your services.

– Mickael
Nov 14 '18 at 10:22













You can give them names: stackoverflow.com/questions/48941960/…

– Thilo
Nov 14 '18 at 10:22





You can give them names: stackoverflow.com/questions/48941960/…

– Thilo
Nov 14 '18 at 10:22













I think that either you will use @Qualifier as suggested by Mickael or you will @Autowire the specific service instead of autowiring the interface.

– Christos K.
Nov 14 '18 at 10:26





I think that either you will use @Qualifier as suggested by Mickael or you will @Autowire the specific service instead of autowiring the interface.

– Christos K.
Nov 14 '18 at 10:26













Sorry guys, I wasn't clear at first. I have updated the description

– Zed
Nov 14 '18 at 10:27





Sorry guys, I wasn't clear at first. I have updated the description

– Zed
Nov 14 '18 at 10:27












1 Answer
1






active

oldest

votes


















1














Two approaches when dealing with multiple implementations:



Use a specific flavour, identified by a @Qualifier



Annotate each implementation with a specific @Qualifier (such as @Qualifier("One") and @Qualifier("Two")), and inject the specific flavour:



@Autowired
@Qualifier("One")
InterfaceOne implementation;


Use all implementations (or evaluate most appropriate with code)



The second approach is useful when you have a strategy interface, and want to have all implementations injected. You can then use all or any of them, and also query them for additional details.



In that case (when expecting 1..n implementations), use:



@Autowired
List<InterfaceOne> implementations;


If the implementations are optional (0..n), use:



@Autowired
Optional<List<InterfaceOne>> implementations;


EDIT: example on how to use a strategy interface with multiple implementations:



Interface:



public interface HelloWorldService 
String sayHello();
String getLanguage();



Implementations:



@Service
public class HelloWorldServiceEN implements HelloWorldService
public String sayHello() return "Hi there!";
public String getLanguage() return "en";


@Service
public class HelloWorldServiceDE implements HelloWorldService
public String sayHello() return "Hallo!";
public String getLanguage() return "de";


@Service
public class HelloWorldServiceFR implements HelloWorldService
public String sayHello() return "Salut!";
public String getLanguage() return "fr";



Usage:



@Autowired
private List<HelloWorldService> helloWorldServices;

public void sayHelloInAllLanguages()
for (HelloWorldService helloWorldService : helloWorldServices)
System.out.println(helloWorldService.sayHello());



public void sayHelloInUserLanguage()
String userLanguage = Locale.getDefault().getLanguage();
HelloWorldService helloWorldService = find(userLanguage);
System.out.println(helloWorldService.sayHello());



private HelloWorldService find(String language)

// find service in specific language
Optional<HelloWorldService> service = helloWorldServices.stream().filter(s -> language.equals(s.getLanguage())).findFirst();
if (service.isPresent())
return service.get();


// fallback to english, if available
service = helloWorldServices.stream().filter(s -> language.equals("en")).findFirst();
if (service.isPresent())
return service.get();


// fallback to any language
return helloWorldServices.stream().findFirst().orElseThrow(IllegalStateException::new);






share|improve this answer

























  • hi, it would be great if you give an example for the use case of Use all implementations. How can a method from ServiceOne implementation be called?

    – Erfan Ahmed
    Nov 15 '18 at 7:10










Your Answer






StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);













draft saved

draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53297846%2finjecting-service-class-by-interface%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









1














Two approaches when dealing with multiple implementations:



Use a specific flavour, identified by a @Qualifier



Annotate each implementation with a specific @Qualifier (such as @Qualifier("One") and @Qualifier("Two")), and inject the specific flavour:



@Autowired
@Qualifier("One")
InterfaceOne implementation;


Use all implementations (or evaluate most appropriate with code)



The second approach is useful when you have a strategy interface, and want to have all implementations injected. You can then use all or any of them, and also query them for additional details.



In that case (when expecting 1..n implementations), use:



@Autowired
List<InterfaceOne> implementations;


If the implementations are optional (0..n), use:



@Autowired
Optional<List<InterfaceOne>> implementations;


EDIT: example on how to use a strategy interface with multiple implementations:



Interface:



public interface HelloWorldService 
String sayHello();
String getLanguage();



Implementations:



@Service
public class HelloWorldServiceEN implements HelloWorldService
public String sayHello() return "Hi there!";
public String getLanguage() return "en";


@Service
public class HelloWorldServiceDE implements HelloWorldService
public String sayHello() return "Hallo!";
public String getLanguage() return "de";


@Service
public class HelloWorldServiceFR implements HelloWorldService
public String sayHello() return "Salut!";
public String getLanguage() return "fr";



Usage:



@Autowired
private List<HelloWorldService> helloWorldServices;

public void sayHelloInAllLanguages()
for (HelloWorldService helloWorldService : helloWorldServices)
System.out.println(helloWorldService.sayHello());



public void sayHelloInUserLanguage()
String userLanguage = Locale.getDefault().getLanguage();
HelloWorldService helloWorldService = find(userLanguage);
System.out.println(helloWorldService.sayHello());



private HelloWorldService find(String language)

// find service in specific language
Optional<HelloWorldService> service = helloWorldServices.stream().filter(s -> language.equals(s.getLanguage())).findFirst();
if (service.isPresent())
return service.get();


// fallback to english, if available
service = helloWorldServices.stream().filter(s -> language.equals("en")).findFirst();
if (service.isPresent())
return service.get();


// fallback to any language
return helloWorldServices.stream().findFirst().orElseThrow(IllegalStateException::new);






share|improve this answer

























  • hi, it would be great if you give an example for the use case of Use all implementations. How can a method from ServiceOne implementation be called?

    – Erfan Ahmed
    Nov 15 '18 at 7:10















1














Two approaches when dealing with multiple implementations:



Use a specific flavour, identified by a @Qualifier



Annotate each implementation with a specific @Qualifier (such as @Qualifier("One") and @Qualifier("Two")), and inject the specific flavour:



@Autowired
@Qualifier("One")
InterfaceOne implementation;


Use all implementations (or evaluate most appropriate with code)



The second approach is useful when you have a strategy interface, and want to have all implementations injected. You can then use all or any of them, and also query them for additional details.



In that case (when expecting 1..n implementations), use:



@Autowired
List<InterfaceOne> implementations;


If the implementations are optional (0..n), use:



@Autowired
Optional<List<InterfaceOne>> implementations;


EDIT: example on how to use a strategy interface with multiple implementations:



Interface:



public interface HelloWorldService 
String sayHello();
String getLanguage();



Implementations:



@Service
public class HelloWorldServiceEN implements HelloWorldService
public String sayHello() return "Hi there!";
public String getLanguage() return "en";


@Service
public class HelloWorldServiceDE implements HelloWorldService
public String sayHello() return "Hallo!";
public String getLanguage() return "de";


@Service
public class HelloWorldServiceFR implements HelloWorldService
public String sayHello() return "Salut!";
public String getLanguage() return "fr";



Usage:



@Autowired
private List<HelloWorldService> helloWorldServices;

public void sayHelloInAllLanguages()
for (HelloWorldService helloWorldService : helloWorldServices)
System.out.println(helloWorldService.sayHello());



public void sayHelloInUserLanguage()
String userLanguage = Locale.getDefault().getLanguage();
HelloWorldService helloWorldService = find(userLanguage);
System.out.println(helloWorldService.sayHello());



private HelloWorldService find(String language)

// find service in specific language
Optional<HelloWorldService> service = helloWorldServices.stream().filter(s -> language.equals(s.getLanguage())).findFirst();
if (service.isPresent())
return service.get();


// fallback to english, if available
service = helloWorldServices.stream().filter(s -> language.equals("en")).findFirst();
if (service.isPresent())
return service.get();


// fallback to any language
return helloWorldServices.stream().findFirst().orElseThrow(IllegalStateException::new);






share|improve this answer

























  • hi, it would be great if you give an example for the use case of Use all implementations. How can a method from ServiceOne implementation be called?

    – Erfan Ahmed
    Nov 15 '18 at 7:10













1












1








1







Two approaches when dealing with multiple implementations:



Use a specific flavour, identified by a @Qualifier



Annotate each implementation with a specific @Qualifier (such as @Qualifier("One") and @Qualifier("Two")), and inject the specific flavour:



@Autowired
@Qualifier("One")
InterfaceOne implementation;


Use all implementations (or evaluate most appropriate with code)



The second approach is useful when you have a strategy interface, and want to have all implementations injected. You can then use all or any of them, and also query them for additional details.



In that case (when expecting 1..n implementations), use:



@Autowired
List<InterfaceOne> implementations;


If the implementations are optional (0..n), use:



@Autowired
Optional<List<InterfaceOne>> implementations;


EDIT: example on how to use a strategy interface with multiple implementations:



Interface:



public interface HelloWorldService 
String sayHello();
String getLanguage();



Implementations:



@Service
public class HelloWorldServiceEN implements HelloWorldService
public String sayHello() return "Hi there!";
public String getLanguage() return "en";


@Service
public class HelloWorldServiceDE implements HelloWorldService
public String sayHello() return "Hallo!";
public String getLanguage() return "de";


@Service
public class HelloWorldServiceFR implements HelloWorldService
public String sayHello() return "Salut!";
public String getLanguage() return "fr";



Usage:



@Autowired
private List<HelloWorldService> helloWorldServices;

public void sayHelloInAllLanguages()
for (HelloWorldService helloWorldService : helloWorldServices)
System.out.println(helloWorldService.sayHello());



public void sayHelloInUserLanguage()
String userLanguage = Locale.getDefault().getLanguage();
HelloWorldService helloWorldService = find(userLanguage);
System.out.println(helloWorldService.sayHello());



private HelloWorldService find(String language)

// find service in specific language
Optional<HelloWorldService> service = helloWorldServices.stream().filter(s -> language.equals(s.getLanguage())).findFirst();
if (service.isPresent())
return service.get();


// fallback to english, if available
service = helloWorldServices.stream().filter(s -> language.equals("en")).findFirst();
if (service.isPresent())
return service.get();


// fallback to any language
return helloWorldServices.stream().findFirst().orElseThrow(IllegalStateException::new);






share|improve this answer















Two approaches when dealing with multiple implementations:



Use a specific flavour, identified by a @Qualifier



Annotate each implementation with a specific @Qualifier (such as @Qualifier("One") and @Qualifier("Two")), and inject the specific flavour:



@Autowired
@Qualifier("One")
InterfaceOne implementation;


Use all implementations (or evaluate most appropriate with code)



The second approach is useful when you have a strategy interface, and want to have all implementations injected. You can then use all or any of them, and also query them for additional details.



In that case (when expecting 1..n implementations), use:



@Autowired
List<InterfaceOne> implementations;


If the implementations are optional (0..n), use:



@Autowired
Optional<List<InterfaceOne>> implementations;


EDIT: example on how to use a strategy interface with multiple implementations:



Interface:



public interface HelloWorldService 
String sayHello();
String getLanguage();



Implementations:



@Service
public class HelloWorldServiceEN implements HelloWorldService
public String sayHello() return "Hi there!";
public String getLanguage() return "en";


@Service
public class HelloWorldServiceDE implements HelloWorldService
public String sayHello() return "Hallo!";
public String getLanguage() return "de";


@Service
public class HelloWorldServiceFR implements HelloWorldService
public String sayHello() return "Salut!";
public String getLanguage() return "fr";



Usage:



@Autowired
private List<HelloWorldService> helloWorldServices;

public void sayHelloInAllLanguages()
for (HelloWorldService helloWorldService : helloWorldServices)
System.out.println(helloWorldService.sayHello());



public void sayHelloInUserLanguage()
String userLanguage = Locale.getDefault().getLanguage();
HelloWorldService helloWorldService = find(userLanguage);
System.out.println(helloWorldService.sayHello());



private HelloWorldService find(String language)

// find service in specific language
Optional<HelloWorldService> service = helloWorldServices.stream().filter(s -> language.equals(s.getLanguage())).findFirst();
if (service.isPresent())
return service.get();


// fallback to english, if available
service = helloWorldServices.stream().filter(s -> language.equals("en")).findFirst();
if (service.isPresent())
return service.get();


// fallback to any language
return helloWorldServices.stream().findFirst().orElseThrow(IllegalStateException::new);







share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 15 '18 at 11:10

























answered Nov 14 '18 at 14:15









Peter WalserPeter Walser

10.6k23755




10.6k23755












  • hi, it would be great if you give an example for the use case of Use all implementations. How can a method from ServiceOne implementation be called?

    – Erfan Ahmed
    Nov 15 '18 at 7:10

















  • hi, it would be great if you give an example for the use case of Use all implementations. How can a method from ServiceOne implementation be called?

    – Erfan Ahmed
    Nov 15 '18 at 7:10
















hi, it would be great if you give an example for the use case of Use all implementations. How can a method from ServiceOne implementation be called?

– Erfan Ahmed
Nov 15 '18 at 7:10





hi, it would be great if you give an example for the use case of Use all implementations. How can a method from ServiceOne implementation be called?

– Erfan Ahmed
Nov 15 '18 at 7:10



















draft saved

draft discarded
















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid


  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53297846%2finjecting-service-class-by-interface%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







這個網誌中的熱門文章

Barbados

How to read a connectionString WITH PROVIDER in .NET Core?

Node.js Script on GitHub Pages or Amazon S3