如何按名称而不是类型自动装配
How to autowire by name instead of type
我知道我不是第一个遇到这个问题的人,但我正在努力在 Spring Boot 2.5.4 中创建多个相同类型的 bean。
我的配置:
@Configuration
public class MapperConfig {
@Bean("yamlMapper")
public ObjectMapper yamlMapper() {
return new ObjectMapper(new YAMLFactory());
}
@Bean("jsonMapper")
public ObjectMapper jsonMapper() {
return new ObjectMapper();
}
}
还有我的服务class:
@Service
@RequiredArgsConstructor
public class MapperService {
@Qualifier("jsonMapper")
private final ObjectMapper jsonMapper;
@Qualifier("yamlMapper")
private final ObjectMapper yamlMapper;
}
错误如下:
No qualifying bean of type 'com.fasterxml.jackson.databind.ObjectMapper' available: expected single matching bean but found 2: yamlMapper,jsonMapper
我尝试了其他 SO 帖子和文档中建议的 @Bean、@Qualifier 等的各种组合,但我似乎无法找到一种方法来使 Spring 按名称自动装配而不是类型。任何帮助将不胜感激!
解决方案:
正如 Youssef 所指出的,未能找到正确的 bean 的不是 MapperService,而是 Spring Boot 的 MappingJackson2HttpMessageConverterConfiguration class。我们无法向该 class 添加注释,因此需要在我们的配置中使用 @Primary。
上下文加载正常,如下所示:
@Configuration
public class MapperConfig {
@Bean
public ObjectMapper yamlMapper() {
return new ObjectMapper(new YAMLFactory());
}
@Bean
@Primary
public ObjectMapper jsonMapper() {
return new ObjectMapper();
}
}
@Service
@RequiredArgsConstructor
public class MapperService {
@Autowired
@Qualifier("jsonMapper")
private final ObjectMapper jsonMapper;
@Autowired
@Qualifier("yamlMapper")
private final ObjectMapper yamlMapper;
}
使用注释:
@Resource
https://www.baeldung.com/spring-annotations-resource-inject-autowire
您的服务:
@Service
public class MapperService {
@Resource(name = "jsonMapper")
private final ObjectMapper jsonMapper;
@Resource(name = "yamlMapper")
private final ObjectMapper yamlMapper;
}
您需要像那样向您的 ObjectMapper
个 bean 添加 @Primary
注释
@Primary
@Bean("jsonMapper")
因为如果您使用 Spring 引导,Jackson
在尝试自动配置时需要它:
Parameter 0 of method mappingJackson2HttpMessageConverter in org.springframework.boot.autoconfigure.http.JacksonHttpMessageConvertersConfiguration$MappingJackson2HttpMessageConverterConfiguration required a single bean, but 2 were found:
但也要注意 @M.Deinum 评论:也可能会破坏内容,因为这也会(部分)禁用 ObjectMapper[=15= 的自动配置]
我知道我不是第一个遇到这个问题的人,但我正在努力在 Spring Boot 2.5.4 中创建多个相同类型的 bean。
我的配置:
@Configuration
public class MapperConfig {
@Bean("yamlMapper")
public ObjectMapper yamlMapper() {
return new ObjectMapper(new YAMLFactory());
}
@Bean("jsonMapper")
public ObjectMapper jsonMapper() {
return new ObjectMapper();
}
}
还有我的服务class:
@Service
@RequiredArgsConstructor
public class MapperService {
@Qualifier("jsonMapper")
private final ObjectMapper jsonMapper;
@Qualifier("yamlMapper")
private final ObjectMapper yamlMapper;
}
错误如下:
No qualifying bean of type 'com.fasterxml.jackson.databind.ObjectMapper' available: expected single matching bean but found 2: yamlMapper,jsonMapper
我尝试了其他 SO 帖子和文档中建议的 @Bean、@Qualifier 等的各种组合,但我似乎无法找到一种方法来使 Spring 按名称自动装配而不是类型。任何帮助将不胜感激!
解决方案:
正如 Youssef 所指出的,未能找到正确的 bean 的不是 MapperService,而是 Spring Boot 的 MappingJackson2HttpMessageConverterConfiguration class。我们无法向该 class 添加注释,因此需要在我们的配置中使用 @Primary。
上下文加载正常,如下所示:
@Configuration
public class MapperConfig {
@Bean
public ObjectMapper yamlMapper() {
return new ObjectMapper(new YAMLFactory());
}
@Bean
@Primary
public ObjectMapper jsonMapper() {
return new ObjectMapper();
}
}
@Service
@RequiredArgsConstructor
public class MapperService {
@Autowired
@Qualifier("jsonMapper")
private final ObjectMapper jsonMapper;
@Autowired
@Qualifier("yamlMapper")
private final ObjectMapper yamlMapper;
}
使用注释:
@Resource
https://www.baeldung.com/spring-annotations-resource-inject-autowire
您的服务:
@Service
public class MapperService {
@Resource(name = "jsonMapper")
private final ObjectMapper jsonMapper;
@Resource(name = "yamlMapper")
private final ObjectMapper yamlMapper;
}
您需要像那样向您的 ObjectMapper
个 bean 添加 @Primary
注释
@Primary
@Bean("jsonMapper")
因为如果您使用 Spring 引导,Jackson
在尝试自动配置时需要它:
Parameter 0 of method mappingJackson2HttpMessageConverter in org.springframework.boot.autoconfigure.http.JacksonHttpMessageConvertersConfiguration$MappingJackson2HttpMessageConverterConfiguration required a single bean, but 2 were found:
但也要注意 @M.Deinum 评论:也可能会破坏内容,因为这也会(部分)禁用 ObjectMapper[=15= 的自动配置]