My query is why is an instance variable null when cglib proxy with spring tries to access it inside a final method. This would mean that even if I had declared the variable directly like in the class below -
class A {
String prop="a";
public final eat(){
return prop;
}
}
The call to the proxy class's eat() method would return null as the method is final. This seems to imply that when the proxy is initialised , the prop variable is set to null .
My current understanding which I want to validate -
Spring internally seems to use SpringObjenesis#newInstance to create a proxy object [ I debugged through the code ]. This seems to create the class instance with all instance variable set to null. When the proxy now tries to return the instance variable , it will return null.
The way Spring uses CGLIB proxies is by a delegation pattern, see this answer for a schematic code sample about how this is implemented.
Please understand that when creating the proxy, only method delegation is being considered. The proxy object's instance fields will not be initialised, because usually at some point the proxy calls the delegate's method. Therefore, the delegate will transparently access its own (initialised) fields.
In case of a
finalmethod, however, no proxy method can be generated, because final methods cannot be overridden. I.e., in this case the original method is called, but when accessing fields via e.g.return myField(a shorthand forreturn this.myField),thisis the proxy instance, because there was no method call delegation to the original object. This explains why the result isnull,0orfalse, depending on the field type.Add an aspect as a simple way to trigger proxy creation:
Running this application yields the following console log:
See? You get the expected value for the non-final method, because delegation to the original object takes place (and the aspect kicks in), but for the final method the result is
null, as explained above.