Java JsonDeserializer中的自动连接:SpringBeanAutowiringSupport vs HandlerInstancer
我已经编写了一个自定义的Java JsonDeserializer中的自动连接:SpringBeanAutowiringSupport vs HandlerInstancer,java,spring,jackson,Java,Spring,Jackson,我已经编写了一个自定义的JsonDeserializer,其中包含一个自动连线服务,如下所示: public class PersonDeserializer extends JsonDeserializer<Person> { @Autowired PersonService personService; @Override public Person deserialize(JsonParser jsonParser, Deserializat
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;
}
}
选项2是使用handler实例化器
并将其注册到myObjectMapper
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;
}
}
@组件
公共类SpringBeanHandlerInstantiator扩展HandlerInstantiator{
@自动连线
私有应用程序上下文应用程序上下文;
@凌驾
公共JsonDeserializer反序列化器实例(反序列化配置,带注释,类>反序列化类){
试一试{
返回(JsonDeserializer)applicationContext.getBean(deserClass);
}捕获(例外e){
//返回null并让默认行为发生
返回null;
}
}
}
@配置
公共类JacksonConfiguration{
@自动连线
Springbeanandleringator Springbeanandleringator;
@豆子
公共对象映射器对象映射器(){
Jackson2ObjectMapperFactoryBean Jackson2ObjectMapperFactoryBean=新Jackson2ObjectMapperFactoryBean();
jackson2ObjectMapperFactoryBean.AfterPropertieSet();
ObjectMapper ObjectMapper=jackson2ObjectMapperFactoryBean.getObject();
//添加自定义处理程序实例化器
setHandlerInstantiator(springBeanHandlerInstantiator);
返回对象映射器;
}
}
我已经尝试了这两种选择,它们同样有效。显然,选项1简单得多,因为它只有三行代码,但我的问题是:与HandlerInstantiator
方法相比,使用SpringBeanAutowiringSupport
是否有任何缺点?我的应用程序将每分钟反序列化数百个对象,如果这有什么区别的话
任何建议/反馈都将不胜感激。如本文所述,您需要创建自定义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);
}
}
<bean id="jacksonObjectMapper" class="com.acme.CustomObjectMapper" />
<bean id="jacksonMessageConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="prefixJson" value="false" />
<property name="supportedMediaTypes" value="application/json" />
<property name="objectMapper" ref="jacksonObjectMapper" />
</bean>
。。。personService将不会为null。添加到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;
}
使用spring boot对上述答案进行清理
@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();
}
您是否发现了SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this)的缺点?很好,谢谢!我最近发现,
Jackson2ObjectMapperBuilder
也有一个流畅的API,使事情变得更加方便:返回Jackson2ObjectMapperBuilder.json().handle实例化器(springhandle实例化器).build()代码>在Spring Boot中(至少在2.0+版本中),JacksonAutoConfiguration应在正确配置handlerInstantiator的情况下自动创建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;
}
@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();
}