我编写了一个包含自动连线服务的自定义JsonDeserializer,如下所示:

public class PersonDeserializer extends JsonDeserializer<Person> {

    @Autowired
    PersonService personService;

    @Override
    public Person deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {

        // deserialization occurs here which makes use of personService

        return person;
    }
}

当我第一次使用此反序列化器时,我得到的是NPE,因为personService没有自动接线。通过查看其他SO答案(特别是this one),看来有两种使 Autowiring 起作用的方法。

选项1是在自定义反序列化器的构造函数中使用SpringBeanAutowiringSupport:
public PersonDeserializer() {

    SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
}

选项2是使用HandlerInstantiator并将其注册到我的ObjectMapper bean中:
@Component
public class SpringBeanHandlerInstantiator extends HandlerInstantiator {

    @Autowired
    private ApplicationContext applicationContext;

    @Override
    public JsonDeserializer<?> deserializerInstance(DeserializationConfig config, Annotated annotated, Class<? extends JsonDeserializer<?>> deserClass) {

        try {

            return (JsonDeserializer<?>) applicationContext.getBean(deserClass);

        } catch (Exception e) {

            // Return null and let the default behavior happen
            return null;
        }
    }
}

@Configuration
public class JacksonConfiguration {

    @Autowired
    SpringBeanHandlerInstantiator springBeanHandlerInstantiator;

    @Bean
    public ObjectMapper objectMapper() {

        Jackson2ObjectMapperFactoryBean jackson2ObjectMapperFactoryBean = new Jackson2ObjectMapperFactoryBean();
        jackson2ObjectMapperFactoryBean.afterPropertiesSet();

        ObjectMapper objectMapper = jackson2ObjectMapperFactoryBean.getObject();

        // add the custom handler instantiator
        objectMapper.setHandlerInstantiator(springBeanHandlerInstantiator);

        return objectMapper;
    }
}

我已经尝试了两种选择,并且它们同样工作良好。显然,选项1容易得多,因为它只有三行代码,但是我的问题是:与SpringBeanAutowiringSupport方法相比,使用HandlerInstantiator是否有任何缺点?我的应用程序每分钟将反序列化数百个对象,如果有什么不同的话。

任何建议/反馈表示赞赏。

最佳答案

添加到Amir Jamak的答案中,您不必创建自定义HandlerInstantiator,因为Spring已经有了它,即SpringHandlerInstantiator。

您需要做的是将其连接到Spring配置中的Jackson2ObjectMapperBuilder。

@Bean
public HandlerInstantiator handlerInstantiator(ApplicationContext applicationContext) {
    return new SpringHandlerInstantiator(applicationContext.getAutowireCapableBeanFactory());
}

@Bean
public Jackson2ObjectMapperBuilder objectMapperBuilder(HandlerInstantiator handlerInstantiator) {
    Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
    builder.handlerInstantiator(handlerInstantiator);
    return builder;
}

07-24 09:20