Affects: All versions
In a Java constructor, the JLS requires:
* No touching this
prior to invoking the superclass constructor
* Superclass constructor must be the first statement (syntatically)
However, the JVM is more lenient: constructors may perform arbitrary work prior to invoking the superclass constructor, as long as that work either doesn't touch this
except for assignments to final variables.
This means that, in theory, by tweaking the bytecode weaving that occurs, @Autowired
fields could be marked final
and their values assigned prior to invoking the superclass constructor.
This would be a great feature and a much cleaner way to avoid problems where @Autowired
fields are not set before use due to superclass method invocation or whatever (i.e., the same problems that preConstruction = true
only partially addresses).
Also, adding this support would be backward compatible, because final
and @Autowired
are currently not possible together.
It would also make Spring look cool because it would show how Spring developers really know their bytecode.
Comment From: quaff
Source file cannot be compiled to bytecode at the first step, there is no chance weaving happens.
Comment From: snicoll
Thanks for the suggestion but we've been suggesting for years to the spring community to move from field injection to constructor injection. What you see as a cool feature can be quite problematic to support in practice and I'd very much rather stick with the JLS here.
Comment From: archiecobbs
OK guys - but I'm a little disturbed that both comments seem to indicate a lack of understanding of what is being asked here.
@quaff wrote:
Source file cannot be compiled to bytecode at the first step, there is no chance weaving happens.
This request has nothing to do with source code, other than allowing something to work that didn't work before.
The actual change would only affect the bytecode weaving process.
@snicoll wrote:
What you see as a cool feature can be quite problematic to support in practice and I'd very much rather stick with the JLS here.
Again, this has nothing to do with the JLS or source code so I no idea what you mean by "stick with the JLS".
Also, could you elaborate on what you mean by "quite problematic to support in practice"?
Comment From: bclozel
I guess that the main problem with that approach is that the developer would need to write illegal Java code in the first place, if it's leaving a final field unassigned.
I'm also in favor of declining this feature. I don't think this is a pattern we want to promote.
Thanks for the suggestion!
Comment From: archiecobbs
Argh, sorry I'm an idiot - of course in the original source code you can't have a final
variable without also assigning something to it.
This feature is still possible (without the final
keyword)... you'd just have to make the field final
as part of the bytecode rewriting... or just assign it to null
and fix that as part of the rewriting.
OK - I agree it's not worth the trouble. Thanks for the discussion.