【发布时间】:2020-06-15 00:14:54
【问题描述】:
我正在尝试找出在 Spring 5 中使用由泛型类型区分的组件的多个副本的最简洁和有效的方法。显然我错过了一个概念,因为根据我所读到的内容,我觉得这(下)应该有效,但它没有,所以我可能误解了泛型类型作为限定符的工作原理。
我有这样的安排:
- 两种具体类型:啤酒和咖啡
- A店
- 订单
- @Autowire 订单 和订单 的 Manager 类
- (然后每个订单
@Autowires a Shop )
public class Beer {}
public class Coffee {}
@Component
public class Order<T> {
@Autowired
Shop<T> shopToSendOrderTo;
void place(int quantity) {
log.info("Inside the order: " + this);
shopToSendOrderTo.sendOrder(quantity);
}
}
@Component
public class Shop<T> {
void sendOrder(int quantity) {
log.info("Inside the shop: " + this);
}
}
@Configuration
public class Manager implements InitializingBean {
@Autowired
Order<Beer> beerOrder;
@Autowired
Order<Coffee> coffeeOrder;
@Override
public void afterPropertiesSet() {
beerOrder.place(2);
coffeeOrder.place(0);
}
}
但是当我想要一个商店 和一个商店 以及一个订单 和一个订单 时,我最终只创建了一个 shop bean 和一个 order bean
我可以从执行器/bean 输出中清楚地看到这一点:
"shop":{
"aliases":[
],
"scope":"singleton",
"type":"com.example.generics.Generics.Shop",
"resource":"file [...]",
"dependencies":[
]
},
"order":{
"aliases":[
],
"scope":"singleton",
"type":"com.example.generics.Generics.Order",
"resource":"...",
"dependencies":[
"shop"
]
}
当您打印此参考时,您会看到每个只有一个:
2020-06-15 00:40:05.600 INFO 849 --- [ restartedMain] c.e.g.Generics.Order : Inside the order: com.example.generics.Generics.Order@70792f0a
2020-06-15 00:40:05.602 INFO 849 --- [ restartedMain] c.e.g.Generics.Shop : Inside the shop: com.example.generics.Generics.Shop@41e7f2d5
2020-06-15 00:40:05.602 INFO 849 --- [ restartedMain] c.e.g.Generics.Order : Inside the order: com.example.generics.Generics.Order@70792f0a
2020-06-15 00:40:05.602 INFO 849 --- [ restartedMain] c.e.g.Generics.Shop : Inside the shop: com.example.generics.Generics.Shop@41e7f2d5
【问题讨论】:
-
行为很复杂并且可能是一个bug,但是如果你想要单独的bean,最直接的方法是使用
@Bean方法。 -
您必须自己创建它们。 Bean 不是基于
@Autowired中的信息创建的,而是基于@Bean信息或通过@Component检测到的。它不会根据您想要的泛型类型自动创建实例(除非您开始为此目的扩展框架)。创建一个构造两个实例的配置类并删除@Component。 -
@M.Deinum 如果我接受你的建议并使用@Bean 注释为 CoffeeOrder 和 BeerOrder 创建一个 bean,在这些 bean 方法中我必须使用
new实例化对象,所以 Shop每个内部都没有自动连接(?)你会如何处理? -
它仍然是一个 bean,spring 也会自动装配。
@Bean与 xml 中的<bean>相同,基本上没有区别 bean 是如何存在的。除非您没有将Order<Coffee>等公开为 bean,而只是实例化它们。您必须确保Shop<Coffee>也可以作为 bean 使用。 -
谢谢,我不知道
@Bean仍然会自动连线。我尝试为我的每个泛型创建具体类型:BeerShop 扩展 Shop等,但又回到了使用 @Bean的想法。自然地,我正在处理的代码库比这个示例更复杂,并且帮助很大。尽管 Spring 不会通过@Beans 中具有泛型类型的 @Autowired属性进行连接,但它仍然更加整洁。谢谢。
标签: java spring spring-boot generics