在JsonDeserializer中自动assembly:SpringBeanAutowiringSupport与HandlerInstantiator

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

 public class PersonDeserializer extends JsonDeserializer { @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没有被自动assembly。 通过查看其他SO答案(特别是这一个 ),似乎有两种方法可以使自动assembly工作。

选项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更容易,因为它只有三行代码,但我的问题是:与HandlerInstantiator方法相比,使用SpringBeanAutowiringSupport有什么缺点吗? 我的应用程序将每分钟反序列化数百个对象,如果这有任何区别的话。

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

添加到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; } 

正如在此评论中所建议的那样,您需要创建自定义HandlerInstantiator:

 import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.stereotype.Component; import com.fasterxml.jackson.databind.DeserializationConfig; import com.fasterxml.jackson.databind.JsonDeserializer; import com.fasterxml.jackson.databind.JsonSerializer; import com.fasterxml.jackson.databind.KeyDeserializer; import com.fasterxml.jackson.databind.SerializationConfig; import com.fasterxml.jackson.databind.cfg.HandlerInstantiator; import com.fasterxml.jackson.databind.cfg.MapperConfig; import com.fasterxml.jackson.databind.introspect.Annotated; import com.fasterxml.jackson.databind.jsontype.TypeIdResolver; import com.fasterxml.jackson.databind.jsontype.TypeResolverBuilder; @Component public class SpringBeanHandlerInstantiator extends HandlerInstantiator { private ApplicationContext applicationContext; @Autowired public SpringBeanHandlerInstantiator(ApplicationContext applicationContext) { this.applicationContext = applicationContext; } @Override public JsonDeserializer deserializerInstance(DeserializationConfig config, Annotated annotated, Class deserClass) { try { return (JsonDeserializer) applicationContext.getBean(deserClass); } catch (Exception e) { // Return null and let the default behavior happen } return null; } @Override public KeyDeserializer keyDeserializerInstance(DeserializationConfig config, Annotated annotated, Class keyDeserClass) { try { return (KeyDeserializer) applicationContext.getBean(keyDeserClass); } catch (Exception e) { // Return null and let the default behavior happen } return null; } @Override public JsonSerializer serializerInstance(SerializationConfig config, Annotated annotated, Class serClass) { try { return (JsonSerializer) applicationContext.getBean(serClass); } catch (Exception e) { // Return null and let the default behavior happen } return null; } @Override public TypeResolverBuilder typeResolverBuilderInstance(MapperConfig config, Annotated annotated, Class builderClass) { try { return (TypeResolverBuilder) applicationContext.getBean(builderClass); } catch (Exception e) { // Return null and let the default behavior happen } return null; } @Override public TypeIdResolver typeIdResolverInstance(MapperConfig config, Annotated annotated, Class resolverClass) { try { return (TypeIdResolver) applicationContext.getBean(resolverClass); } catch (Exception e) { // Return null and let the default behavior happen } return null; } } 

自定义ObjectMapper:

 import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.databind.cfg.HandlerInstantiator; public class CustomObjectMapper extends ObjectMapper { private static final long serialVersionUID = -8865944893878900100L; @Autowired ApplicationContext applicationContext; public JamaxObjectMapper() { // Problems serializing Hibernate lazily initialized collections? Fix here. // HibernateModule hm = new HibernateModule(); // hm.configure(com.fasterxml.jackson.module.hibernate.HibernateModule.Feature.FORCE_LAZY_LOADING, true); // this.registerModule(hm); // Jackson confused by what to set or by extra properties? Fix it. this.setSerializationInclusion(JsonInclude.Include.NON_NULL); this.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); this.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); } @Override @Autowired public Object setHandlerInstantiator(HandlerInstantiator hi) { return super.setHandlerInstantiator(hi); } } 

并注册您的自定义ObjectMapper:

       

此时你可以使用:

 @JsonDeserialize(contentUsing=PersonDeserializer.class) public void setPerson(Person person) { ... } 

…而personService不会为null。

使用弹簧靴清理上述答案,

 @Bean public HandlerInstantiator handlerInstantiator(ApplicationContext context) { return new SpringHandlerInstantiator(context.getAutowireCapableBeanFactory()); } @Bean public ObjectMapper objectMapper(HandlerInstantiator handlerInstantiator) { Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder(); builder.handlerInstantiator(handlerInstantiator); return builder.build(); }