首页 > 解决方案 > 如何通过 Autowired 注入具有不同配置的不同 ObjectMapper?

问题描述

我正在尝试拥有 2 个不同ObjectMapper的 Jackson ,以便我可以在代码中使用其中任何一个进行切换。2 ObjectMappers 的配置会有一些细微差别。

在我的配置文件中,我将它们作为 2 种不同的方式使用:

@Configuration
public class ApplicationConfiguration {
    private ObjectMapper createMapper() {
        ObjectMapper mapper = new ObjectMapper();
        mapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
        // And a few more other common configurations
        return mapper;
    }

    @Bean
    @Qualifier("standardObjectMapper")
    public ObjectMapper standardObjectMapper() {
        ObjectMapper mapper = createMapper();
        SimpleModule module = new SimpleModule();
        module.addSerializer(Product.class, new StandardProductSerializer());
        mapper.registerModule(module);
        return mapper;
    }

    @Bean
    @Qualifier("specialObjectMapper")
    public ObjectMapper specialObjectMapper() {
        ObjectMapper mapper = createMapper();
        SimpleModule module = new SimpleModule();
        // In this mapper, I have a different serializer for the Product class
        module.addSerializer(Product.class, new SpecialProductSerializer());
        mapper.registerModule(module);
        return mapper;
    }
}

我的计划是在需要时注入和使用其中一个映射器。所以在我的测试中,我有这样的事情:

class SerializationTest {
    @Autowired
    @Qualifier("standardObjectMapper")
    private ObjectMapper standardObjectMapper;

    @Autowired
    @Qualifier("specialObjectMapper")
    private ObjectMapper specialObjectMapper;

    @Test
    void testSerialization() throws JsonProcessingException {
       Product myProduct = new Product("Test Product");

      String stdJson = objectMapper.writeValueAsString(myProduct);
      String specialJson = specialObjectMapper.writeValueAsString(myProduct);

      // Both stdJson and specialJson are of the same value even though they should be different because the mappers have different serializers!
    }
}

但是,似乎 2ObjectMapperstandardObjectMapper两者specialObjectMapper都使用相同的StandardProductSerializer.

我希望specialObjectMapper使用 the ,SpecialProductSerializer但事实并非如此。

2个ObjectMapper不应该不同吗?我假设注入将基于他们各自的名字,因为他们的类型是相同的?

我应该怎么做才能解决这个问题,以便 2 个 ObjectMapper 可以使用不同的序列化器?


更新:

我试过使用Qualifiers,但我收到一个错误,即找不到 bean:

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'com.site.SerializationTest': Unsatisfied dependency expressed through field 'standardObjectMapper'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.fasterxml.jackson.databind.ObjectMapper' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true), @org.springframework.beans.factory.annotation.Qualifier(value="standardObjectMapper")}

标签: javaspringspring-bootjackson

解决方案


添加@Qualifier应该可以解决您的问题

@Bean
@Qualifier("standardMapper")
public ObjectMapper standardObjectMapper() {
    ObjectMapper mapper = createMapper();
    SimpleModule module = new SimpleModule();
    module.addSerializer(Product.class, new StandardProductSerializer());
    mapper.registerModule(module);
    return mapper;
}

@Bean
@Qualifier("specialMapper")
public ObjectMapper specialObjectMapper() {
    ObjectMapper mapper = createMapper();
    SimpleModule module = new SimpleModule();
    // In this mapper, I have a different serializer for the Product class
    module.addSerializer(Product.class, new SpecialProductSerializer());
    mapper.registerModule(module);
    return mapper;
}

然后加上@Qualifier你的@Autowired

@Autowired
@Qualifier("standardMapper")
private ObjectMapper standardObjectMapper;

@Autowired
@Qualifier("specialMapper")
private ObjectMapper specialObjectMapper;

推荐阅读