简体   繁体   English

自定义 Jackson 解串器不会注入 @Autowired 字段

[英]Custom Jackson deserializer doesn't inject into @Autowired fields

I'm trying to inject my config into my custom StdDeserializer .我正在尝试将我的配置注入我的自定义StdDeserializer The problem however is, even though I marked the class as @Component , the value of the field is never injected.然而问题是,即使我将 class 标记为@Component ,该字段的值也不会被注入。 The injection works without any problems in the other places of the application.注入在应用程序的其他地方没有任何问题。

Therefore, I've come to the conclusion that the problem is with the way the deserializer is working, since it doesn't get instantiated by us but rather like the example down here:因此,我得出的结论是,问题出在反序列化器的工作方式上,因为它没有被我们实例化,而是像下面的示例一样:

ClassToDeserialize myClass = new ObjectMapper().readValue(mockJson, ClassToDeserialize.class);

As you can see there is no explicit usage of my custom deserializer ClassToDeserializeDeserializer hence it detects the classes with the custom deserializer with the @JsonDeserialize(using = ClassToDeserialize.class) annotation.如您所见,我的自定义反序列化器ClassToDeserializeDeserializer没有显式使用,因此它使用带有@JsonDeserialize(using = ClassToDeserialize.class)注释的自定义反序列化器检测类。

Class that should be deserialized应该反序列化的 Class

@Data
@AllArgsConstructor
@SuperBuilder
@JsonDeserialize(using = MyClassDeserializer.class)
public class MyClass{
  private final String field1;
  private final String field2;
}

Config class that should be injected配置应注入的 class

@Configuration
@ConfigurationProperties(prefix = "myconfig")
@Data
@AllArgsConstructor
@NoArgsConstructor
public class MyConfig {
   private final String confField1;
   private final String confField2;
}

MyClass's custom deserializer: MyClass 的自定义反序列化器:

@Component
public class MyClassDeserializer extends StdDeserializer<MyClass> {

    @Autowired
    MyConfig myConfig;

    public MyClassDeserializer () {
        this(null);
    }

    public MyClassDeserializer (Class<?> vc) {
        super(vc);
    }

    @Override
    public MyClassDeserializer deserialize(JsonParser parser, DeserializationContext context)
            throws IOException, JsonProcessingException {

         //Deserializing code that basically tries to read from myConfig
         myConfig.getConfField1(); //Hello NullPointerException my old friend
    }

}

Usage of the deserializer解串器的使用

MyClass myClass = new ObjectMapper().readValue(mockJson, MyClass.class);

Reason why it doesn't work:不起作用的原因:

Jackson doesn't know anything about Spring Boot stuff, so when you readValue(..) Jackson sees @JsonDeserialize annotation with deserializer class and creates new instance of the deserializer (it doesn't pick up the bean, but rather just new MyClassDeserializer(..) ), that is why you never see MyConfig being injected. Jackson doesn't know anything about Spring Boot stuff, so when you readValue(..) Jackson sees @JsonDeserialize annotation with deserializer class and creates new instance of the deserializer (it doesn't pick up the bean, but rather just new MyClassDeserializer(..) ),这就是为什么您永远不会看到MyConfig被注入的原因。

If you want to make it work, you need to somehow register this deserializer through Spring Boot, for example, like this: How to provide a custom deserializer with Jackson and Spring Boot如果你想让它工作,你需要通过 Spring Boot 以某种方式注册这个解串器,例如: How to provide a custom deserializer with Jackson and Z38008DD81C2F4D7985ECF6EZCE8 Boot

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM