如何在春季使用通用型<T>的自动线豆?

我有一个豆子,需要在类中自动连接。Item<T>@Configuration

@Configuration
public class AppConfig {

    @Bean
    public Item<String> stringItem() {
        return new StringItem();
    }

    @Bean
    public Item<Integer> integerItem() {
        return new IntegerItem();
    }

}

但是当我尝试时,我得到以下例外。@Autowire Item<String>

"No qualifying bean of type [Item] is defined: expected single matching bean but found 2: stringItem, integerItem"

我应该如何在春季自动布线通用类型?Item<T>


答案 1

简单的解决方案是升级到Spring 4.0,因为它会自动将泛型视为的一种形式,如下所示:@Qualifier

@Autowired
private Item<String> strItem; // Injects the stringItem bean

@Autowired
private Item<Integer> intItem; // Injects the integerItem bean

事实上,您甚至可以在注入列表时自动连接嵌套的泛型,如下所示:

// Inject all Item beans as long as they have an <Integer> generic
// Item<String> beans will not appear in this list
@Autowired
private List<Item<Integer>> intItems;

这是如何工作的?

新的 ResolvableType 类提供了实际使用泛型类型的逻辑。您可以自己使用它来轻松导航和解析类型信息。上的大多数方法本身都会返回一个,例如:ResolvableTypeResolvableType

// Assuming 'field' refers to 'intItems' above
ResolvableType t1 = ResolvableType.forField(field); // List<Item<Integer>> 
ResolvableType t2 = t1.getGeneric(); // Item<Integer>
ResolvableType t3 = t2.getGeneric(); // Integer
Class<?> c = t3.resolve(); // Integer.class

// or more succinctly
Class<?> c = ResolvableType.forField(field).resolveGeneric(0, 0);

在下面的链接中查看示例和教程。

希望这对您有所帮助。


答案 2

如果您不想升级到Spring 4,则必须按名称自动布线,如下所示:

@Autowired
@Qualifier("stringItem")
private Item<String> strItem; // Injects the stringItem bean

@Autowired
@Qualifier("integerItem")
private Item<Integer> intItem; // Injects the integerItem bean

推荐