3

This is more of a best practice type question.

I've heard dozens of times that:

a) when autowiring in Spring it is best practice to autowire the interface 'not' the implementation.

and..

b) I have also heard that if you only have 'one' implementation, then you should not really be using an interface.

Here is my dilemma, I have an interface 'MyService' and one implementation MyServiceImpl. I use @Autowiredz MyService inMyController` and in 'MyServiceTest'.

I have no need for another implementation.

Clearly this violates rule b), but autowiring the implementation would violate rule a).

So my question is .... what should I do? Should I just opt not to use Spring at all in this case and just instantiate 'MyService' using the new keyword?

M. Deinum
  • 115,695
  • 22
  • 220
  • 224
Johnny Alpha
  • 758
  • 1
  • 8
  • 35
  • 1
    Dont use new keyword! If you use new keyword the service is not in the context of spring anymore. – Patrick Dec 27 '16 at 09:19
  • Thanks, so what would be the best practice in this situation? To lose the interface altogether and just autowire the implementation? Or to keep it as it is with an autowired inteface (even though I only have one implementation?). – Johnny Alpha Dec 27 '16 at 09:21

5 Answers5

4

You should Autowire the interface because this way when you would like to change the implementation later on, you will only need to add @Qualifier above the @Autowire and not change the names in the code. It is also better for testing purposes when you are injecting mock implementation.

Prasanna Kumar H A
  • 3,341
  • 6
  • 24
  • 52
TomOw
  • 1,311
  • 1
  • 11
  • 18
4

There is no definite answer. If it makes sense, use an interface. Don't be the guy who uses interfaces for everything because they're "better". This isn't a Spring specific concept.

If it's a single implementation unlikely to be modified and is exclusive to your application, go ahead and skip the interface. There's no real benefit to using one if this is a single, proprietary implementation that's never going to leave your application. Even if it changes often, if it's a single class exclusive to an application, as long as the behavior (Expected inputs and outputs) doesn't change, you still don't need an interface.

If you're a producer and other applications are likely to use your code, use an interface. This allows consumption of your library where you can tinker with the code to your heart's desire as long as you stick to the interface (meaning you don't change the behavior, but change the implementation).

If you do use an interface, Autowire the interface, not the implementation.

Christopher Schneider
  • 3,745
  • 2
  • 24
  • 38
2

I will suggest you to use interface because in future if anyone wants to enhance/implement, it will be useful.

And there is nowhere stated that it is strictly prohibited to violate rule b. You can go with only rule of having @Autowired on interface and @Component on implementations.

For more info go with this answer

Community
  • 1
  • 1
Prasanna Kumar H A
  • 3,341
  • 6
  • 24
  • 52
  • I have one more option I believe. At the moment I use moks (mockMvc) to test my controller. I could instead create a MyServiceStub implementation and inject it into the controller. – Johnny Alpha Dec 27 '16 at 10:12
  • Any thoughts on that solution? – Johnny Alpha Dec 27 '16 at 10:13
  • I think this answer is a lot more fitting, coming from Spring[boot] 4. I would like to add though, that rule b is not a very maintainable solution AND if your software demands maintainability, should be abolished completely. As other answers mention, ignoring rule b is at least good for tests. – RabbitBones22 Apr 24 '18 at 17:00
1

The practice is code to Interface not Implementation. If you always try to code to Interface then your code is much more flexible and loosely coupled. So should strive to practice option a).

But there counter arguments for this. Many other distinguished Developers believe that an Interface is not required unless until you have multiple implementations. In the case of only single Implementation you can @Autowire the class directly. It will not be the end of the world and will not increase or decrease performance drastically. But as I mentioned before option a) code is much more flexible and loosely coupled than option b).

shazin
  • 21,379
  • 3
  • 54
  • 71
1

I suggest to use an interface because I like to have the opportunity to create another implementation even I dont need one at the moment. But applications will change in developing phase or later. There is still one person which needs another requirement.

So for me its clear, be open for changes in future.

Patrick
  • 12,336
  • 15
  • 73
  • 115