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