This week's book giveaway is in the Go forum.
We're giving away four copies of Head First Go and have Jay McGavren on-line!
See this thread for details.
Win a copy of Head First Go this week in the Go 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 all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Liutauras Vilda
  • Bear Bibeault
  • Paul Clapham
  • Jeanne Boyarsky
Sheriffs:
  • Devaka Cooray
  • Junilu Lacar
  • Tim Cooke
Saloon Keepers:
  • Tim Moores
  • Ron McLeod
  • Tim Holloway
  • Claude Moore
  • Stephan van Hulst
Bartenders:
  • Winston Gutkowski
  • Carey Brown
  • Frits Walraven

Two constructors annotation with @Autowired , which one to use  RSS feed

 
Ranch Hand
Posts: 1724
12
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,
If there are two constructors annotated with @Autowired, which one the container will use to inject beans to the constructor?
According to the document:


As of Spring Framework 4.3, an @Autowired annotation on such a constructor is no longer necessary if the target bean only defines one constructor to begin with. However, if several constructors are available, at least one must be annotated to teach the container which one to use.



The document does not say which constructor to use in order to inject beans by constructor.

Thanks in advanced.

Reference: https://docs.spring.io/spring/docs/4.3.22.RELEASE/spring-framework-reference/htmlsingle/#beans-autowired-annotation
 
Saloon Keeper
Posts: 20514
115
Android Eclipse IDE Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Have you tried it? It's quite possible that Spring will simply throw an Exception complaining about the conflict.
 
Himai Minh
Ranch Hand
Posts: 1724
12
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi, Tim.
That is true. I tried to create a @Service bean with two constructors. I annotated both with @Autowired.
IntelliJ won't compile it because only one constructor can have @Autowired annotation.

The Spring document does not say we cannot annotate more than one constructor with @Autowired.
 
Tim Holloway
Saloon Keeper
Posts: 20514
115
Android Eclipse IDE Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Welcome to the wonderful world of computer documentation.

Too often things are left unsaid because the people involved didn't think about the edge cases or omitted mentioning things that "can/should never happen". Such, alas, is life.

Myself, I do tend to worry about such things, but then I get slammed by the boss for not being "productive". They just want to "get it done".

Is it really IntelliJ that fails the compile, or is it the Java compiler itself? The annotation's internal logic may be detecting the violation.
 
Himai Minh
Ranch Hand
Posts: 1724
12
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I used Spring boot to demo my example. I guess it is actually the Spring boot does not let me declare two constructors with @Autowired.
But according to the specification about Autowired:


...If multiple non-required constructors declare the annotation, they will be considered as candidates for autowiring.



But still, if two constructors are annotated with @Autowired, the container does not really know which constructor should use.

Reference:
https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/beans/factory/annotation/Autowired.html
 
Sheriff
Posts: 21653
101
Chrome Eclipse IDE Java Spring Ubuntu VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The annotation Javadoc tells you which constructor will be picked - the one with the highest number of arguments that can be resolved. There will probably be an exception if there is still ambiguity because several methods have the same highest number of resolvable arguments.

Tim Holloway wrote:Is it really IntelliJ that fails the compile, or is it the Java compiler itself? The annotation's internal logic may be detecting the violation.


It can't the Java compiler, because there is no way yet to indicate an annotation can only occur once in a class. The only limitations are where the annotation can be put (the target).

IntelliJ is quite smart about a lot of framework annotations. It probably has built-in support for Spring annotations.
 
Tim Holloway
Saloon Keeper
Posts: 20514
115
Android Eclipse IDE Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Rob Spoor wrote:
It can't the Java compiler, because there is no way yet to indicate an annotation can only occur once in a class.



Not so. Who do you think compiles the annotation? Annotations can basically be designated for either compile-time processing or run-time processing. At compile time, it's certainly not impossible to detect that the same method (or constructor, in this instance) is annotated more than once.
 
Rob Spoor
Sheriff
Posts: 21653
101
Chrome Eclipse IDE Java Spring Ubuntu VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Yes, the Java compiler can catch that one constructor has the same annotation twice. Unless the annotation is repeatable (since Java 8), that's a compiler error. But what the Java compiler cannot (yet) catch is that two constructors have the same annotation (once each). I can write a class with two @Autowired constructors and the Java compiler will not complain. IntelliJ is a bit smarter apparently because it does complain.
 
Tim Holloway
Saloon Keeper
Posts: 20514
115
Android Eclipse IDE Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It wouldn't be the compiler that I'd expect to catch the fault. At least not directly. The syntax doesn't support it. However, the annotation's processor code could do so, if it so desired.

You've answered my question in regards to autowired Spring constructors, though. The Spring @Autowired annotation processor doesn't check - it's the IDE that catches it here.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!