JsonDeserializer 中的自动装配:SpringBeanAutowiringSupport 与 HandlerInstantiator [英] Autowiring in JsonDeserializer: SpringBeanAutowiringSupport vs HandlerInstantiator

查看:20
本文介绍了JsonDeserializer 中的自动装配:SpringBeanAutowiringSupport 与 HandlerInstantiator的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

public class PersonDeserializer extends JsonDeserializer{@自动连线人员服务人员服务;@覆盖public Person deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) 抛出 IOException, JsonProcessingException {//这里使用了 personService 进行反序列化归还人;}}

当我第一次使用这个解串器时,我得到了 NPE,因为 personService 没有被自动装配.从查看其他 SO 答案(特别是这个)来看,似乎有两种方法可以使自动装配工作.>

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

public PersonDeserializer() {SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);}

选项 2 是使用 HandlerInstantiator 并将其注册到我的 ObjectMapper bean:

@Component公共类 SpringBeanHandlerInstantiator 扩展 HandlerInstantiator {@自动连线私有 ApplicationContext applicationContext;@覆盖公共 JsonDeserializerdeserializerInstance(DeserializationConfig config, Annotated annotated, Class deserClass) {尝试 {返回 (JsonDeserializer) applicationContext.getBean(deserClass);} 捕获(异常 e){//返回 null 并让默认行为发生返回空;}}}@配置公共类 JacksonConfiguration {@自动连线SpringBeanHandlerInstantiator springBeanHandlerInstantiator;@豆角,扁豆公共 ObjectMapper objectMapper() {Jackson2ObjectMapperFactoryBean jackson2ObjectMapperFactoryBean = new Jackson2ObjectMapperFactoryBean();jackson2ObjectMapperFactoryBean.afterPropertiesSet();ObjectMapper objectMapper = jackson2ObjectMapperFactoryBean.getObject();//添加自定义处理程序实例化器objectMapper.setHandlerInstantiator(springBeanHandlerInstantiator);返回对象映射器;}}

这两个选项我都试过,效果都一样好.显然选项 1 容易得多,因为它只有三行代码,但我的问题是:与 HandlerInstantiator 方法相比,使用 SpringBeanAutowiringSupport 有什么缺点吗?我的应用程序将每分钟反序列化数百个对象,如果这有什么不同的话.

感谢任何建议/反馈.

解决方案

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

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

@Bean公共 HandlerInstantiator handlerInstantiator(ApplicationContext applicationContext) {返回新的 SpringHandlerInstantiator(applicationContext.getAutowireCapableBeanFactory());}@豆角,扁豆公共 Jackson2ObjectMapperBuilder objectMapperBuilder(HandlerInstantiator handlerInstantiator) {Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();builder.handlerInstantiator(handlerInstantiator);返回生成器;}

I have written a custom JsonDeserializer which contains an autowired service, as follows:

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;
    }
}

When I first made use of this deserializer I was getting NPEs as personService was not being autowired. From looking at other SO answers (in particular, this one) it appears there is two ways of getting the autowiring to work.

Option 1 is to use SpringBeanAutowiringSupport within the constructor of the custom deserializer:

public PersonDeserializer() { 

    SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this); 
}

Option 2 is to use a HandlerInstantiator and register it with my 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;
    }
}

I have tried both options and they work equally well. Clearly option 1 is much easier as it's only three lines of code, but my question is: are there any disadvantages to using SpringBeanAutowiringSupport compared to the HandlerInstantiator approach? My application is going to be deserializing hundreds of objects per minute, if that makes any difference.

Any advice/feedback is appreciated.

解决方案

Adding to the Amir Jamak's answer, you don't have to create custom HandlerInstantiator as Spring has it already which is SpringHandlerInstantiator.

What you need to do is to hook it up to Jackson2ObjectMapperBuilder in Spring configuration.

@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;
}

这篇关于JsonDeserializer 中的自动装配:SpringBeanAutowiringSupport 与 HandlerInstantiator的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆