• 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 all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Ron McLeod
  • Paul Clapham
  • Bear Bibeault
  • Junilu Lacar
Sheriffs:
  • Jeanne Boyarsky
  • Tim Cooke
  • Henry Wong
Saloon Keepers:
  • Tim Moores
  • Stephan van Hulst
  • Tim Holloway
  • salvin francis
  • Frits Walraven
Bartenders:
  • Scott Selikoff
  • Piet Souris
  • Carey Brown

How is this interface working? -- Is it Spring magic or am I missing something?

 
Ranch Hand
Posts: 40
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I'm working on a large application that uses Spring Boot. In it, an interface is used in a way that I don't understand.
I've stripped down the code to the only parts that I think are relevant to the question. There are four files that I have put in order of application flow.

A controller object is created.
It is told to process some stuff.
The controller tells an interface processor to do the work.
There is a processor that implements the interface processor.

It was my understanding that when using an interface you'd do something like:
In other words, assigning the interface an implementation. But in this sample program it seems the processor implementation is implicitly assigned, not in the code as far as I can tell. I'm trying to figure out if this is some Spring wizardry or if I'm just understanding interfaces wrong:









If the ProcessorController class contained something like this:



I think it would make sense since we've linked the interface with its implementation. But it isn't that way. So what is going on here? Any help is appreciated!
 
Marshal
Posts: 15887
265
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Hans Hovan wrote:
If the ProcessorController class contained something like this:
So part of the ProcessorController class would look like this instead:



I think it would make sense since we've linked the interface with its implementation. But it isn't that way. So what is going on here? Any help is appreciated!


If you do that, you've negated the usefulness of programming to an interface instead of an implementation. This design would be far inferior to the other since it's programmed to a specific implementation. What you're seeing is Spring's @Autowire magic in action where it will find a class marked with @Component and inject it into something marked as @Autowired that takes an IProcessor implementation. It can be any IProcessor implementation and not a particular one. This creates a "seam" in your program where you can switch out the implementation with a different one, say for testing purposes, and the program should still work as expected.
 
Junilu Lacar
Marshal
Posts: 15887
265
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I suspect your confusion stems from an incorrect assumption of how @Autowired works in Spring. Look up assignment compatibility in Java. That's basically what Spring uses to determine what can be autowired to what. Essentially, when you have a variable or parameter declared as an interface type, any object that implements that interface is assignment-compatible with it.
 
Sheriff
Posts: 22002
107
Eclipse IDE Spring VI Editor Chrome Java Ubuntu Windows
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
And you either need to have just one such implementation, or mark one with @Primary. Otherwise Spring can't decide which one to use and will just fail instead.
 
Hans Hovan
Ranch Hand
Posts: 40
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Junilu Lacar wrote:

Hans Hovan wrote:
If the ProcessorController class contained something like this:
So part of the ProcessorController class would look like this instead:



I think it would make sense since we've linked the interface with its implementation. But it isn't that way. So what is going on here? Any help is appreciated!


If you do that, you've negated the usefulness of programming to an interface instead of an implementation. This design would be far inferior to the other since it's programmed to a specific implementation. What you're seeing is Spring's @Autowire magic in action where it will find a class marked with @Component and inject it into something marked as @Autowired that takes an IProcessor implementation. It can be any IProcessor implementation and not a particular one. This creates a "seam" in your program where you can switch out the implementation with a different one, say for testing purposes, and the program should still work as expected.



Thanks much for the explanation. Really appreciate it. Follow-up question: What if there were two classes that implemented IProcessor though? How would Spring know which one to use?

Edit: It looks like this was already answered in Rob's post. Makes sense. Thanks.
 
Master Rancher
Posts: 4668
49
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
If you have multiple  Components implementing the same interface just give them a name.
Spring uses the bean name to try and disambiguate.
Failing that you can use the @Qualifier annotation.


Without the @Qualifier annotation Spring would not know what to inject, however if the attribute in the service was called firstClass rather than myInterface then Spring would inject the bean that was called firstClass.
 
I've been selected to go to the moon! All thanks to this tiny ad:
Building a Better World in your Backyard by Paul Wheaton and Shawn Klassen-Koop
https://coderanch.com/wiki/718759/books/Building-World-Backyard-Paul-Wheaton
    Bookmark Topic Watch Topic
  • New Topic