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 collection of optional elements should not crash when no candidates are found [SPR-15858] #20413

Closed
spring-issuemaster opened this Issue Aug 10, 2017 · 0 comments

Comments

Projects
None yet
2 participants
@spring-issuemaster
Copy link
Collaborator

commented Aug 10, 2017

Antonio Anzivino opened SPR-15858 and commented

Hi,

I have an optional dependency to listener beans in one of my beans. That means that I could have any number of listeners in my Application context.

I have tried to annotate my bean the following way:

@Autowired(required = false)
@Lazy
private List<Listener> listeners = new ArrayList<>(0);

IMO it is intuitive that Spring will

  1. Search for Listener beans only when accessed
  2. Do not crash if no Listener bean is defined in the context, namely return an empty list

I don't know if this is a bug in 4.3.5 or is it just how Spring is designed, but the above code, when no Listener bean is defined, crashes instead of returning an empty list when I try to access the listeners object.

If I use eager initialization, Autowired's required=false injects an empty list. I expected similar behaviour for lazy lists.

This ticket is:

  • MINOR because I can workaround this issue by using eager initialization, for the mometn
  • IMPROVEMENT because I have found no documentation on whether it is a design choice or an implementation issue

My container bean's afterPropertiesSet does

log.info("I have {} listeners attached", listeners.size());

Instead of logging 0, the application crashes with the following stack trace

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'java.util.List<Manager$Listener>' available: Optional dependency not present for lazy injection point
	at org.springframework.context.annotation.ContextAnnotationAutowireCandidateResolver$1.getTarget(ContextAnnotationAutowireCandidateResolver.java:85)
	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:192)
	at com.sun.proxy.$Proxy172.size(Unknown Source)
	at com.acme.ManagerImpl.afterPropertiesSet(ManagerImpl.java:75)

Before submitting a test case, I'd first like to be clarified what is the expected Spring's behaviour in such situation

I have reviewed Spring docs on Lazy. The javadoc does not cite the case of optional Collection-dependencies
https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/context/annotation/Lazy.html

In addition to its role for component initialization, this annotation may also be placed on injection points marked with Autowired or Inject: In that context, it leads to the creation of a lazy-resolution proxy for all affected dependencies, as an alternative to using ObjectFactory or Provider.

Affects: 4.3.5

Issue Links:

  • #20384 Autowire contract is not honored in cases where FactoryBean or @Bean return null

Referenced from: commits ec1eafc, 80bf394

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.