Spring Wiring 泛型类型的动态 bean

Neo*_*Neo 4 java generics spring autowired

使用 Spring 5.0.3 使用BeanDefinitionRegistryPostProcessor. 代码如下:

class MyBDRRPP implements BeanDefinitionRegistryPostProcessor {

   public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
     // values - hardcoded for now
     List<String> values = Arrays.asList("1", "22", "333");
     registry.registerBeanDefinition("myDynamicBean", 
        BeanDefinitionBuilder.genericBeanDefinition(List.class, () -> values);
   }
}

// Register MyBDRRPP with ApplicationContext - not shown here

// Consumer of the dynamic bean
class MyConsumer {

   MyConsumer(@Qualifier("myDynamicBean") List<String> data) {
      // do something with data
   }
}
Run Code Online (Sandbox Code Playgroud)

当 MyConsumer 类连接时,我收到此异常

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'java.util.List<java.lang.String>' available: expected at least 1 bean which qualifies as autowire candidate.

如果我将构造函数更改为使用raw列表类型,则它可以工作(没有接线问题)。

MyConsumer(@Qualifier("myDynamicBean") List data) {
   // this works
}
Run Code Online (Sandbox Code Playgroud)

我应该如何注册我的动态 bean 以便我可以使用泛型类型?有没有办法在注册 bean 时向 Spring 提供有关类型的一些提示?

Neo*_*Neo 6

我最终是这样做的:

class MyBDRRPP implements BeanDefinitionRegistryPostProcessor {

   public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
     // values - hardcoded for now
     List<String> values = Arrays.asList("1", "22", "333");

     // OLD Code  
     // registry.registerBeanDefinition("myDynamicBean", BeanDefinitionBuilder.genericBeanDefinition(List.class, () -> values);

     // New Code
     RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(List.class, () -> values);
     // Add the generic info
     rootBeanDefinition.setTargetType(ResolvableType.forClassWithGenerics(List.class, String.class));
     registry.registerBeanDefinition("myDynamicBean", rootBeanDefinition);  
   }
}
Run Code Online (Sandbox Code Playgroud)

现在,它已在 MyConsumer 类中正确连接。