【问题标题】:Spring-using library defined beans conflict with applicationSpring使用库定义的bean与应用程序冲突
【发布时间】:2015-08-13 14:49:59
【问题描述】:

我有几个 spring-boot web 应用程序和一个所有 web 应用程序都使用的集成库。集成库将 Spring 用于 DI,并定义了几个自己的 @Beans,并指定了明确的名称,特别是 ObjectMapper 用于从 API 调用中进行自己的反序列化。

这是集成库中的ObjectMapper bean 定义(在@Configuration 类中):

@Bean(name = "Blah.APIObjectMapper")
public ObjectMapper blahAPIObjectMapper() {
    ObjectMapper mapper = new ObjectMapper()
        .configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false)
        .setPropertyNamingStrategy(PropertyNamingStrategy.CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES);

    return mapper;
}

在图书馆的其他地方,这个ObjectMapper@Autowired 加上一个特定的@Qualifier,就像这样:

@Autowired
@Qualifier("Blah.APIObjectMapper")
private ObjectMapper blahAPIObjectMapper;

问题出现在 Web 应用程序中。集成库中定义的这个自定义 ObjectMapper bean 与我无法控制的默认配置 ObjectMapper bean 冲突。

错误是:

org.springframework.beans.factory.UnsatisfiedDependencyException:在类路径资源 [org/springframework/boot/autoconfigure/web/JacksonHttpMessageConvertersConfiguration$MappingJackson2HttpMessageConverterConfiguration.class] 中定义的名称为 'mappingJackson2HttpMessageConverter' 创建 bean 时出错:通过构造函数参数表示的不满足的依赖关系,类型为 [com.fasterxml.jackson.databind.ObjectMapper] 的索引为 0::没有定义 [com.fasterxml.jackson.databind.ObjectMapper] 类型的合格 bean:预期的单个匹配 bean 但找到2:Blah.APIObjectMapper,_halObjectMapper;嵌套异常是 org.springframework.beans.factory.NoUniqueBeanDefinitionException: 没有定义 [com.fasterxml.jackson.databind.ObjectMapper] 类型的合格 bean:预期单个匹配 bean 但找到 2:Blah.APIObjectMapper,_halObjectMapper强>


问:如何防止库的 Blah.APIObjectMapper 与 spring-boot 默认 ObjectMapper 显然命名为 _halObjectMapper 冲突?

我没有为 Spring 使用任何 XML 配置。一切都是基于注释的。

【问题讨论】:

    标签: java spring autowired spring-bean


    【解决方案1】:

    _halObjectMapper 看起来像 spring-hateoas 通过 @EnableHypermediaSupport 创建的 bean 的名称。

    如果存在多个 ObjectMapper 类型的 bean,则 Spring boot 接受名称为 objectMapper 的 bean。因此,您可以通过创建名为 objectMapper 的第三个对象映射器 bean 来解决此问题,甚至可以使用现有的 ObjectMapper bean 之一。

    @Bean
    public ObjectMapper objectMapper(ObjectMapper _halObjectMapper) {
       return _halObjectMapper;
    }
    

    【讨论】:

    【解决方案2】:

    您可以将 ObjectMapper bean 定义为主要提供者。这是一个例子。

    @Primary
    @Bean(name = "Blah.APIObjectMapper")
    public ObjectMapper blahAPIObjectMapper() {
    

    问题和解决方案在this thread进行了讨论。

    【讨论】:

      【解决方案3】:

      我解决了它交换 Hateoas 库:

      之前:

      <dependency>
        <groupId>org.springframework.hateoas</groupId>
        <artifactId>spring-hateoas</artifactId>
      </dependency>
      

      之后:

      <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-hateoas</artifactId>
      </dependency>
      

      【讨论】:

        猜你喜欢
        • 2019-08-10
        • 2017-09-12
        • 2016-11-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-05-02
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多