Java 番石榴ImmutableBiMap变为LinkedHashMap并导致Spring自动布线错误
我有两个简单的SpringBean填充的ImmutableBiMap 操作系统:Manjaro Linux JDK版本:1.8.0.102 Oracle Spring版本:4.3.4.0从发布Java 番石榴ImmutableBiMap变为LinkedHashMap并导致Spring自动布线错误,java,spring,guava,Java,Spring,Guava,我有两个简单的SpringBean填充的ImmutableBiMap 操作系统:Manjaro Linux JDK版本:1.8.0.102 Oracle Spring版本:4.3.4.0从发布 <groupId>io.spring.platform</groupId> <artifactId>platform-bom</artifactId> <version>Athens-SR1</version> 如下屏幕所示,当Sp
<groupId>io.spring.platform</groupId>
<artifactId>platform-bom</artifactId>
<version>Athens-SR1</version>
如下屏幕所示,当Spring的BeanUtil参数引发异常时,它是LinkedHashMap而不是BiMap
最小、完整且可验证的示例:
@Component
@Slf4j
public class TestControl {
private final BiMap<String, Integer> automatons;
@Autowired
public TestControl(BiMap<String, Integer> automatons) {
this.automatons = automatons;
log.info("automatons={}", automatons.keySet());
}
}
@Configuration
public class TextContext {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(
TextContext.class,
TestControl.class
);
BiMap bean = context.getBean(BiMap.class);
}
@Bean
BiMap<String, Integer> automatons() {
return ImmutableBiMap.of(
"Cellular Automaton", cellularAutomaton(),
"Monte Carlo Automaton", monteCarloAutomaton());
}
@Bean
Integer cellularAutomaton() {
return 6;
}
@Bean
Integer monteCarloAutomaton() {
return 5;
}
}
@组件
@Slf4j
公共类测试控制{
专用最终BiMap自动机;
@自动连线
公共测试控制(BiMap自动机){
this.automatons=自动机;
log.info(“automatons={}”,automatons.keySet());
}
}
@配置
公共类文本上下文{
公共静态void main(字符串[]args){
ApplicationContext上下文=新注释ConfigApplicationContext(
TextContext.class,
TestControl.class
);
BiMap bean=context.getBean(BiMap.class);
}
@豆子
BiMap自动机(){
返回不可变的BIMAP.of(
“细胞自动机”,细胞自动机(),
“蒙特卡罗自动机”,蒙特卡罗自动机();
}
@豆子
整型纤维素Automaton(){
返回6;
}
@豆子
整数Montecarloutomaton(){
返回5;
}
}
除非Spring中有一个巨大的bug(我对此表示怀疑),否则这一定是人为/编辑错误
我重新创建了一个比较简单的示例,与我刚才使用的字符串、整数、Long和Boolean相同,因为我没有您的类型-这个简单的示例很有效
LinkedHashMap不是BiMap,因此如果选择它作为autowire候选,它将是一个bug。听起来源代码和编译后的代码几乎不同步,您是否尝试删除生成文件夹并重新生成
如果重建没有帮助,解决这个问题的唯一方法就是进行老式的调试
编辑正如另一个答案中所述,这是Spring的一个限制。也就是说,我最终复制了错误,并通过Spring代码在大约1小时内找到了这种行为的确切代码。我觉得许多开发人员忽视了调试作为一项软件规程。对我来说,这是最重要的一项纪律,因为您可能大部分时间都在处理代码,所以您不是自己编写的。除非Spring中有一个巨大的bug(我怀疑),否则这一定是人为/编辑错误 我重新创建了一个比较简单的示例,与我刚才使用的字符串、整数、Long和Boolean相同,因为我没有您的类型-这个简单的示例很有效 LinkedHashMap不是BiMap,因此如果选择它作为autowire候选对象,它将是一个错误。听起来源代码和编译的代码几乎不同步,您是否尝试删除生成文件夹并重新生成 如果重建没有帮助,解决这个问题的唯一方法就是进行老式的调试
Map
s也可以自动连接,只要所需的键类型为
String
。Map
值将包含预期类型的所有bean,
键将包含相应的bean名称:[……]
A是一张地图
Spring并没有试图将您的自动机bean注入TestControl
。相反,它试图找到所有类型为Integer
的bean作为值,将它们收集到映射中(LinkedHashMap
作为选择的实现),并将它们与bean名称关联作为键
在这种情况下,它会失败,因为构造函数需要一个BiMap
一个
@Component
@Slf4j
public class TestControl {
private final BiMap<String, Integer> automatons;
@Autowired
public TestControl(BiMap<String, Integer> automatons) {
this.automatons = automatons;
log.info("automatons={}", automatons.keySet());
}
}
@Configuration
public class TextContext {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(
TextContext.class,
TestControl.class
);
BiMap bean = context.getBean(BiMap.class);
}
@Bean
BiMap<String, Integer> automatons() {
return ImmutableBiMap.of(
"Cellular Automaton", cellularAutomaton(),
"Monte Carlo Automaton", monteCarloAutomaton());
}
@Bean
Integer cellularAutomaton() {
return 6;
}
@Bean
Integer monteCarloAutomaton() {
return 5;
}
}
@Autowired()
public TestControl(@Qualifier(value = "automatons") BiMap<String, Integer> automatons) {
this.automatons = automatons;
}
@Resource(name = "automatons") // if you don't specify the name element, Spring will try to use the field name
private BiMap<String, Integer> automatons;