Alexandre Navarro opened SPR-13585 and commented

Impossible to inject a Generic type (like List<String>) to create a @Bean via an argument of the method even though with using @Named.

A full example to describe the problem:

@Configuration
public class AppConfiguration {

    private static final Logger LOGGER = LoggerFactory.getLogger(AppConfiguration.class);

    @Bean
    public Map<String, String> map() {
        Map<String, String> map = new HashMap<>();
        for (int i = 0; i < 10; i++) {
            map.put("" + i, "" + i);
        }
        return map;
    }


    // Does not work, inject does not work for a generic type
    // Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [java.lang.String] found for dependency [map with value type java.lang.String]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@javax.inject.Named(value=map)}
    @Bean
    public List<String> list2( @Named("map") Map<String, String> map) {
        return new ArrayList<>(map.values());
    }

    // Work 
    @Resource(name = "map")
    private Map<String, String> map;


    // Work
    @Bean
    public List<String> list() {
        return new ArrayList<>(this.map.values());
    }



    /**
     * <p>main.</p>
     *
     * @param args
     */
    public static void main(String[] args) {

        final ApplicationContext context = 
        new AnnotationConfigApplicationContext(AppConfiguration.class);
        final Map<String, String> map = (Map<String, String>) context.getBean("map");
        LOGGER.info("map={}", map);
        final List<String> list = (List<String>) context.getBean("list");
        LOGGER.info("list={}", list);
//        final List<String> list2 = (List<String>) context.getBean("list2");
//        LOGGER.info("list2={}", list2);
    }


}

For me, it should work. Tell if I did something wrong or if it exists a work around just via annotation on arguments of a @Bean method (I don't want to use Wrapper class of a GenericType or @Resource the bean wanted in a field in the Configuration file like in the example).


Affects: 4.2.2

Issue Links: - #15894 Make spring support like CDI @Produces (for Array/Map/Collection inject) ("is duplicated by") - #12570 Allow for normal bean wiring semantics for types assignable to Map - #16794 @Autowired does not work for target bean of type Collection

Referenced from: commits https://github.com/spring-projects/spring-framework/commit/4a0fa69ce469cae2e8c8a1a45f0b43f74a74481d

Comment From: spring-projects-issues

Juergen Hoeller commented

I'm afraid this is by design, since @Named is just a qualifier that narrows the set of autowire candidates, not an override for the basic Collection/Map processing that @Autowired/@Inject implies.

That said, we are aware that this can be unintuitive for such scenarios and are considering to provide some solution for such scenarios in the 4.3 timeframe.

Juergen

Comment From: spring-projects-issues

Alexandre Navarro commented

Thanks

Comment From: sbrannen

If you have shown interest in this issue, you may also be interested in the following which is currently scheduled for inclusion in Spring Framework 6.1.

  • 30022