spring singleton bean fields are not populated
Are you curious or you have some real issue? Nevertheless here is an explanation.
When using CGLIB to proxy classes Spring will create a subclass called something like myService$EnhancerByCGLIB
. This enhanced class will override some if not all of your business methods to apply cross-cutting concerns around your actual code.
Here comes the real surprise. This extra subclass does not call super
methods of the base class. Instead it creates second instance of myService
and delegates to it. This means you have two objects now: your real object and CGLIB enhanced object pointing to (wrapping) it.
The enhanced class is just a dummy proxy. It still has the same fields as your base class (inherited from it) but they are not used. When you call addToList()
on myService$EnhancerByCGLIB
object it will first apply some AOP logic, call addToList()
of myService
(which it wraps) and apply remaining AOP logic on return. The myService$EnhancerByCGLIB.list
field is never touched.
Why can't Spring use the same class and delegate via super
? I guess for simplicity: first create "raw" bean and then apply AOP proxying during post-processing.
"This field will be populated for sure by someone before getSomething() is called"
By someone? No, the Spring bean factory. If you don't configure it, nothing will be populated.
Not every bean needs to be under Spring's control. It sounds like you want to have a List
that clients can add and remove items to in a thread-safe way. If that's true, remove the @Autowired
annotation, create a new List
, and expose methods to add and remove.
I'd recommend a List from the new concurrent collections.
CGLIB will proxy protected getters.
So you can have:
@Autowired
private Monitor monitor;
protected Monitor getMonitor() { return monitor; }
public List getSomething(){
return getMonitor().getList();
}
getMonitor() will be proxied to call getMonitor() on the other instance which has monitor injected.