• 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
  • Paul Clapham
  • Jeanne Boyarsky
  • Junilu Lacar
  • Henry Wong
Sheriffs:
  • Ron McLeod
  • Devaka Cooray
  • Tim Cooke
Saloon Keepers:
  • Tim Moores
  • Stephan van Hulst
  • Frits Walraven
  • Tim Holloway
  • Carey Brown
Bartenders:
  • Piet Souris
  • salvin francis
  • fred rosenberger

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

 
Ranch Hand
Posts: 39
  • 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: 15630
264
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: 15630
264
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: 21949
106
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: 39
  • 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.
 
Rancher
Posts: 4576
47
  • 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 am mighty! And this is a mighty small ad:
Devious Experiments for a Truly Passive Greenhouse!
https://www.kickstarter.com/projects/paulwheaton/greenhouse-1
    Bookmark Topic Watch Topic
  • New Topic