Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lazy annotation throws exception if non-required bean does not exist #27649

Closed
nytro77 opened this issue Nov 6, 2021 · 3 comments
Closed

Lazy annotation throws exception if non-required bean does not exist #27649

nytro77 opened this issue Nov 6, 2021 · 3 comments
Assignees
Labels
in: core Issues in core modules (aop, beans, core, context, expression) status: backported An issue that has been backported to maintenance branches type: documentation A documentation task
Milestone

Comments

@nytro77
Copy link

nytro77 commented Nov 6, 2021

Affects: 5.3.12


A bean is defined in a @Configuration class that has a @Profile annotation, so the bean only exists under certain conditions.

In another bean a setter is annotated with @Autowired(required = false) for that bean.
If the bean exists it should be injected. If not, then not much to do about that.
The code will check if the bean is injected (not null) and take appropriate actions.

Now for the problem. If the bean does exist, it needs to be lazy loaded to avoid circular dependency issues.
So, the setter is annotated with @Lazy annotation.
The lazy annotation causes exception "Optional dependency not present for lazy injection point" if the non-required bean does not exist.

The exception says exactly whats happening, so perhaps this is by design then?
I cannot tell from the documentation if this is a use case that is expected to work or not.

In addition to its role for component initialization, you can also place the @lazy annotation on injection points marked with @Autowired or @Inject. In this context, it leads to the injection of a lazy-resolution proxy

Perhaps this behaviour can be changed to lazy load the injection of the non-required bean if it is actually available, and if not then just ignore the @Lazy annotation since the @Autowired annotation itself did nothing?

The problem is reproduced in this GitHub project: https://github.com/nytro77/spring-lazy-bug

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged or decided on label Nov 6, 2021
@jhoeller jhoeller self-assigned this Nov 7, 2021
@jhoeller
Copy link
Contributor

jhoeller commented Nov 7, 2021

I'm afraid this is by design indeed. @Lazy injection implies lazy-by-proxy, and the determination of whether the target bean actually exists happens lazily on invocation. So you'll always get the proxy, even if the bean eventually does not exist on invocation of the proxy's methods. The required=false part is effectively overridden by the pre-existence of the proxy.

Maybe ObjectProvider<TheThing> is a better fit for your purposes? You could do ifAvailable interactions there on demand - for programmatic late determination of existence versus non-existence of the target bean, without any proxy involved.

@nytro77
Copy link
Author

nytro77 commented Nov 7, 2021

@jhoeller Thank you! ObjectProvider was exactly the thing i was looking for. Works like a charm :)

@jhoeller jhoeller added in: core Issues in core modules (aop, beans, core, context, expression) type: documentation A documentation task and removed status: waiting-for-triage An issue we've not yet triaged or decided on labels Nov 7, 2021
@jhoeller
Copy link
Contributor

jhoeller commented Nov 7, 2021

Good to hear :-)

I'll turn this into a documentation issue, clarifying @Lazy behavior and adding stronger references to ObjectProvider from wherever @Lazy is mentioned.

@jhoeller jhoeller added this to the 5.3.13 milestone Nov 7, 2021
@jhoeller jhoeller added the for: backport-to-5.2.x Marks an issue as a candidate for backport to 5.2.x label Nov 9, 2021
@spring-projects-issues spring-projects-issues added status: backported An issue that has been backported to maintenance branches and removed for: backport-to-5.2.x Marks an issue as a candidate for backport to 5.2.x labels Nov 9, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: core Issues in core modules (aop, beans, core, context, expression) status: backported An issue that has been backported to maintenance branches type: documentation A documentation task
Projects
None yet
Development

No branches or pull requests

3 participants