• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

multiple implementations for interface - use default implementation for auto wiring

 
Sebastian Janisch
Ranch Hand
Posts: 1183
  • Mark post as helpful
  • send pies
  • 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

 
Mark Spritzler
ranger
Sheriff
Posts: 17278
6
IntelliJ IDE Mac Spring
  • Mark post as helpful
  • send pies
  • 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
  • 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
Sheriff
Posts: 17278
6
IntelliJ IDE Mac Spring
  • Mark post as helpful
  • send pies
  • 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
 
Adolfo Eloy
Ranch Hand
Posts: 146
Eclipse IDE Java Linux
  • Mark post as helpful
  • send pies
  • 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
 
Bill Gorder
Bartender
Posts: 1682
7
Android IntelliJ IDE Linux Mac OS X Spring
  • Mark post as helpful
  • send pies
  • 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/
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic