I found that, when I use @Lazy
on @Resource
fields, Spring injects a lazy proxy.
The lazy proxy's TargetSource
is not static, so every time I invoke a method on the lazy proxy, it calls beanFactory.resolveDependency()
to resolve the target object.
Why doesn't Spring set the lazy proxy's TargetSource
to static?
If so, it will be faster when invoking the lazy proxy's methods.
For example, in CommonAnnotationBeanPostProcessor
:
protected Object buildLazyResourceProxy(final LookupElement element, final @Nullable String requestingBeanName) {
TargetSource ts = new TargetSource() {
@Override
public Class<?> getTargetClass() {
return element.lookupType;
}
@Override
public boolean isStatic() {
// this place: why not use "true"?
return false;
}
@Override
public Object getTarget() {
return getResource(element, requestingBeanName);
}
@Override
public void releaseTarget(Object target) {
}
};
// ...
}
Comment From: sbrannen
Why doesn't Spring set the lazy proxy's
TargetSource
to static?
That's a good question. I imagine that having a static TargetSource
(which caches the resolved target bean) might make sense if the underlying bean is a singleton, but I may be overlooking something.
While looking into this issue, I noticed another issue which I reported in #28176.
The team will investigate both of these related issues.
As a side note, please note that this issue applies not only to @Lazy @Resource
fields but also to @Lazy @Autowired
injection points. Thus, this issue applies to both CommonAnnotationBeanPostProcessor.buildLazyResourceProxy(...)
and ContextAnnotationAutowireCandidateResolver.buildLazyResolutionProxy(...)
.
Comment From: sbrannen
The reason that CommonAnnotationBeanPostProcessor
and ContextAnnotationAutowireCandidateResolver
both build a proxy for a @Lazy
injection point with a non-static TargetSource
is in order to allow the BeanFactory
to dynamically determine how the bean is resolved. This is true even for singleton target beans in order to support edge cases where a BeanDefinition
may have been removed since the last time the proxy was invoked.
In light of that, the team has decided to close this issue as "works as designed".
However, if you discover that the use of a non-static TargetSource
in such cases leads to a performance bottleneck for a real application, please provide a sample project that reproduces the issue.
Thanks