Java Jackson ObjectMapper在春季的生命周期
环境: 我使用SpringBootVersion2.3.3.0版本Java Jackson ObjectMapper在春季的生命周期,java,json,spring,spring-boot,jackson,Java,Json,Spring,Spring Boot,Jackson,环境: 我使用SpringBootVersion2.3.3.0版本 问题 我使用@JsonComponent注释注册自定义反序列化程序 在一些模块和测试中,I@AutowirejacksonsObjectMapper 问题1:我无法在@JsonComponent中使用@Autowire ObjectMapper,否则@JsonComponent将被完全忽略(没有错误消息) 问题2:我希望在@JsonComponent中有相同的ObjectMapper实例(或者至少有相同配置的OM),我可以通过
问题 我使用
@JsonComponent
注释注册自定义反序列化程序
在一些模块和测试中,I@Autowire
jacksonsObjectMapper
问题1:我无法在@JsonComponent中使用@Autowire ObjectMapper,否则@JsonComponent将被完全忽略(没有错误消息)
问题2:我希望在@JsonComponent中有相同的ObjectMapper实例(或者至少有相同配置的OM),我可以通过Autowire在其他组件中获得该实例
示例 由于我不希望对某些字段进行自定义反序列化,因此在自定义反序列化程序中使用ObjectMapper来使用
convertValue()
我注意到,我无法@Autowire
在我的任何反序列化程序中使用ObjectMapper,或者不会为我的应用程序中自动连接的其他ObjectMapper选择配置(因此反序列化程序没有正确注册)
我使用(ObjectMapper)jsonParser.getCodec()在反序列化程序中获取ObjectMapper代码>
但此ObjectMapper配置不正确(例如,忽略类/方法上的注释)
我想按如下方式反序列化我的对象:
@Test
void testDeserializeFoo() throws IOException {
ObjectMapper om = new ObjectMapper(); // this is obtained by jsonParser in deserializer but it behaves the same, since the ObjectMapper lacks the configuration
InputStream is = getClass().getResourceAsStream("/json/foo.json");
JsonNode fooNode = om.readTree(is);
Foo foo = om.convertValue(fooNode, Foo.class);
log.info("Foo: " + foo);
}
Foo的构造函数用@JsonCreator
注释
问题是,我从自定义反序列化程序中的解析器获得的ObjectMapper忽略了此注释。这将导致以下错误消息:
类型的类型定义无效
Foo
:
参数#0没有属性名,不可注入:不能用作
创建者[用于
福,
注释:{接口
com.fasterxml.jackson.annotation.JsonCreator=@com.fasterxml.jackson.annotation.JsonCreator(mode=DEFAULT)}]
自动连线时,我的自定义反序列化程序中是否可能有其他组件中使用的同一个ObjectMapper实例
编辑
可能的解决方案/测试:
我是这样测试我的反序列化程序的:
private JsonParser getJsonParser(String resource) throws IOException {
InputStream src = getInputStream(resource);
return objectMapper.createParser(src);
}
@Test
void testDeserializeFoo() throws IOException {
JsonParser parser = getJsonParser("/json/foo.json");
Foo foo = deserializer.deserialize(parser, null);
System.out.println(foo);
}
问题在于getParser()方法中的objectMapper始终是一个新实例。现在我使用自动连线的objectMapper。但这有什么影响呢
结论:
我希望在JsonComponents(自定义反序列化程序)中使用与自动连线ObjectMapper(由spring在其他组件中提供)相同的ObjectMapper实例,或者至少使用具有相同配置的ObjectMapper
对于配置,我的意思是:在类、方法、字段/注册模块和JSONComponent上启用Jackson特性/注释配置
有人能解释一下吗:
- 如何以及何时在Spring中配置ObjectMapper(何时配置
注释配置(JsonCreator、JsonProperty)、功能
application.yml中的配置(如接受大写),自定义
在ObjectMapper上注册的JsonComponents等
- 此objectMapper实例的生命周期是什么
- ContextConfiguration的生命周期是什么,
反序列化配置
- Spring和Jackson的上下文是如何相互关联的
我寻找相关主题,其他相关答案,其中:
- Spring和Jackson的上下文不一样(但为什么,这意味着什么?)
- 您需要一个HandlerInstantiator来自动连线(我假设这在我的spring版本中已经是默认的,而且这也不能解释为什么在其中一个反序列化程序中自动连线ObjectMapper时,我的自定义反序列化程序不会在没有任何错误消息的情况下被拾取)
通常,您可以使用Jackson2ObjectMapperBuilder和build()在应用所有最新设置的情况下生成新的对象映射器实例。默认对象映射器由JackonAutoConfiguration中的JackonObjectMapPerConfiguration提供。所有jackson2对象映射器生成器实例均由JacksonAutoConfiguration中的JacksonObjectMapperBuilderConfiguration创建。可以查看有关配置对象映射器的详细信息被发现
如果不喜欢JacksonAutoConfiguration中的标准默认值,可以使用Jackson2ObjectMapperBuilderCustomizerConfiguration进一步自定义jackson2对象映射器生成器
签出此-它将回答您的其他问题
出现问题-使用jackson2objectbuilder/build或autowiring对象映射器(用于带有JsonComponent注释的ser/deser)时出现相同问题。所有这些注释都由JacksonAutoConfiguration中定义的JsonComponentModule bean扫描,并使用默认对象映射器和Jackson2o创建的所有实例注册对象映射器生成器。因此,不可能使用未构建的对象映射器同时注册ser/deser。您是对的,spring抑制了异常(BeanCurrentlyIncrementException),json组件模块未注册对象映射器的消息Unsolvale循环引用
除了在spring managed之外创建一个新的对象映射器,我没有找到任何解决方案。我读了你的问题大约3次,仍然不知道你在问什么或试图实现什么。看起来你想向Jackson注册一些东西,它也将使用Jackson aka循环依赖项。好的,我将尝试使这个更c李尔。我稍后会编辑它。尽管底部的问题应该是清晰的,与上面的问题无关。@ManuelWaltschek请更清晰、更专注。看起来你试图在一篇文章中问几个问题。你是否尝试创建一个bean,返回已配置的ObjectMapper
的实例?@LHCHIN是的,正如svr在回答中所说的,这仍然会导致未解析的循环依赖项/引用。谢谢,这就是我所寻找的!因此我可以在Jackson2ObjectMapperB类型的配置中创建一个Bean