Win a copy of TDD for a Shopping Website LiveProject this week in the Testing forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Paul Clapham
  • Ron McLeod
  • Jeanne Boyarsky
  • Tim Cooke
Sheriffs:
  • Liutauras Vilda
  • paul wheaton
  • Henry Wong
Saloon Keepers:
  • Tim Moores
  • Tim Holloway
  • Stephan van Hulst
  • Carey Brown
  • Frits Walraven
Bartenders:
  • Piet Souris
  • Himai Minh

multiple implementations for interface - use default implementation for auto wiring

 
Ranch Hand
Posts: 1183
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi :-)

let's say I have two different implementations for one interface, which are both published into the spring IOC container.

When another class references this interface using the auto wiring mechanism, and I fire up the application context, the whole thing blows up because spring does not know which implementation to inject.

Is it possible to specify a default implementation which is to be used in such case?


thanks for your help guys

 
ranger
Posts: 17346
11
Mac IntelliJ IDE Spring
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
There are many approaches to resolve ambiguity.

1) Use @Qualifier next to your @Autowired so you can tell which one to inject by name.



2) Put @Primary on one of the implementations, then Spring will inject that one.



3) Only have one of the two implementations in your classpath at runtime, so that there will ever only be one implementation.

For 3, I have yet to see any good examples of why you would need multiple implementations of a Service or a Repository or a Controller, EndPoint, or any other class that you write.

However, there are cases where you might have multiple DataSources, TransactionManagers, or other infrastructure beans. In which case, you only have option #1, because you can't put @Primary into a class you didn't write and only have the .class of.

Good Luck

Mark
 
Sebastian Janisch
Ranch Hand
Posts: 1183
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi there

there @Primary was what I was looking for.

I don't like using the @qualifier annotation, as the service consuming component should not know any of the implementation details. and narrowing down the component dependency using the @qualifier annotation kind of transfers this knowledge.


Thanks for your help
 
Mark Spritzler
ranger
Posts: 17346
11
Mac IntelliJ IDE Spring
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Sebastian Janisch wrote:
I don't like using the @qualifier annotation, as the service consuming component should not know any of the implementation details. and narrowing down the component dependency using the @qualifier annotation kind of transfers this knowledge.


Thanks for your help



Yes it does.

Again in most applications you won't have two OrderRepository implementations in your classpath at runtime. If it is some form of Pooling or other reasons why you have such a thing. A good trick to do is have a Pool object that @Autowired into a Collection. Spring will find all the beans of that type and automatically put it into a Collection to assign that @Autowired on it. Now your pool is in control of which one actually gets used in your other objects.

@Autowired
public List<OrderRepository orderRepositories;

Mark
 
Ranch Hand
Posts: 146
Eclipse IDE Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Mark Spritzler wrote:There are many approaches to resolve ambiguity.

1) Use @Qualifier next to your @Autowired so you can tell which one to inject by name.



2) Put @Primary on one of the implementations, then Spring will inject that one.



3) Only have one of the two implementations in your classpath at runtime, so that there will ever only be one implementation.

For 3, I have yet to see any good examples of why you would need multiple implementations of a Service or a Repository or a Controller, EndPoint, or any other class that you write.

However, there are cases where you might have multiple DataSources, TransactionManagers, or other infrastructure beans. In which case, you only have option #1, because you can't put @Primary into a class you didn't write and only have the .class of.

Good Luck

Mark



I have an example of using multiple implementations of a Service.
I'm working on a project that need fake service implementations. I do not need mock at this case... Suppose I have a specific service which collect data from any database but I can't use this service when working at some new functionality that depends on this service. I'd like to use another implementation which returns fake data only to continue working.

Even considering this example, I think using Qualifier or Primary is not a better approach because I don't want that programmers need to change code but instead some kind of config file.

Any ideas?

thanks
 
Bartender
Posts: 1682
7
Android Mac OS X IntelliJ IDE Spring Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
1. package your fake stuff in a separate web-app or module so that once its use is no longer required in can be discarded. I take this approach sometimes for dependencies on 3rd party services that are not available when running on my local dev environment.
2. For dependencies that are environment specific use spring profiles which have been available since Spring 3.1. See the below 2 links:
http://blog.springsource.com/2011/02/11/spring-framework-3-1-m1-released/
http://blog.springsource.org/2011/02/14/spring-3-1-m1-introducing-profile/
 
Enjoy the full beauty of the english language. Embedded in this tiny ad:
free, earth-friendly heat - a kickstarter for putting coin in your pocket while saving the earth
https://coderanch.com/t/751654/free-earth-friendly-heat-kickstarter
reply
    Bookmark Topic Watch Topic
  • New Topic