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;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With