Skip to content

Direct autowiring of existing collection subtype bean if ApplicationContext contains beans of type T #30022

Closed
@yvasyliev

Description

@yvasyliev

The current focus of this issue is described in #30022 (comment).

For background information, the original issue title and description follow.


Previous title: "Cannot autowire java.util.Queue<T> if ApplicationContext contains beans of type T"

Affects: spring-context 5.3.25


I'm not able to autowire java.util.Queue in console app using spring-context.

There is a quick code example:

public interface Action {
    void doAction();
}
public class Action1 implements Action {
    @Override
    public void doAction() {
        System.out.println(this.getClass().getName());
    }
}
public class Action2 implements Action {
    @Override
    public void doAction() {
        System.out.println(this.getClass().getName());
    }
}
public class ActionManager {
    @Autowired
    private Queue<Action> actionQueue;

    public void doActions() {
        actionQueue.forEach(Action::doAction);
    }
}
@Configuration
public class Config {
    @Bean
    public ActionManager actionManager() {
        return new ActionManager();
    }

    @Bean
    public Queue<Action> actionQueue() {
        Queue<Action> actionQueue = new ArrayDeque<>();
        actionQueue.add(action1());
        actionQueue.add(action2());
        return actionQueue;
    }

    @Bean
    public Action action1() {
        return new Action1();
    }

    @Bean
    public Action action2() {
        return new Action2();
    }
}
public class Main {
    public static void main(String[] args) {
        ApplicationContext context = new AnnotationConfigApplicationContext(Config.class);
        ActionManager actionManager = context.getBean(ActionManager.class);
        actionManager.doActions();
    }
}

When I run this code, I receive the next error in console:

Feb 24, 2023 9:16:11 AM org.springframework.context.support.AbstractApplicationContext refresh
WARNING: Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'actionManager': Unsatisfied dependency expressed through field 'actionQueue'; nested exception is org.springframework.beans.ConversionNotSupportedException: Failed to convert value of type 'java.util.LinkedHashMap$LinkedValues' to required type 'java.util.Queue'; nested exception is java.lang.IllegalStateException: Cannot convert value of type 'java.util.LinkedHashMap$LinkedValues' to required type 'java.util.Queue': no matching editors or conversion strategy found
Exception in thread "main" org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'actionManager': Unsatisfied dependency expressed through field 'actionQueue'; nested exception is org.springframework.beans.ConversionNotSupportedException: Failed to convert value of type 'java.util.LinkedHashMap$LinkedValues' to required type 'java.util.Queue'; nested exception is java.lang.IllegalStateException: Cannot convert value of type 'java.util.LinkedHashMap$LinkedValues' to required type 'java.util.Queue': no matching editors or conversion strategy found
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.resolveFieldValue(AutowiredAnnotationBeanPostProcessor.java:660)
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:640)
	at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:119)
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:399)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1431)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:619)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542)
	at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:955)
	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:918)
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583)
	at org.springframework.context.annotation.AnnotationConfigApplicationContext.<init>(AnnotationConfigApplicationContext.java:93)
	at app.Main.main(Main.java:8)
Caused by: org.springframework.beans.ConversionNotSupportedException: Failed to convert value of type 'java.util.LinkedHashMap$LinkedValues' to required type 'java.util.Queue'; nested exception is java.lang.IllegalStateException: Cannot convert value of type 'java.util.LinkedHashMap$LinkedValues' to required type 'java.util.Queue': no matching editors or conversion strategy found
	at org.springframework.beans.TypeConverterSupport.convertIfNecessary(TypeConverterSupport.java:76)
	at org.springframework.beans.TypeConverterSupport.convertIfNecessary(TypeConverterSupport.java:45)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveMultipleBeans(DefaultListableBeanFactory.java:1471)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1349)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1311)
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.resolveFieldValue(AutowiredAnnotationBeanPostProcessor.java:657)
	... 15 more
Caused by: java.lang.IllegalStateException: Cannot convert value of type 'java.util.LinkedHashMap$LinkedValues' to required type 'java.util.Queue': no matching editors or conversion strategy found
	at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:262)
	at org.springframework.beans.TypeConverterSupport.convertIfNecessary(TypeConverterSupport.java:73)
	... 20 more

Note 1: If I replace @Autowired with @javax.annotation.Resource, the code will work.
Note 2: If I replace java.util.Queue with java.util.Set, the code will work.

Since the issue is reproduced for java.util.Queue only, it seems like a bug.

Metadata

Metadata

Assignees

Labels

in: coreIssues in core modules (aop, beans, core, context, expression)type: enhancementA general enhancement

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions