Reputation: 788
I'm trying to inject my config into my custom StdDeserializer
. The problem however is, even though I marked the class as @Component
, the value of the field is never injected. 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.
@Data
@AllArgsConstructor
@SuperBuilder
@JsonDeserialize(using = MyClassDeserializer.class)
public class MyClass{
private final String field1;
private final String field2;
}
@Configuration
@ConfigurationProperties(prefix = "myconfig")
@Data
@AllArgsConstructor
@NoArgsConstructor
public class MyConfig {
private final String confField1;
private final String confField2;
}
@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
}
}
MyClass myClass = new ObjectMapper().readValue(mockJson, MyClass.class);
Upvotes: 0
Views: 2420
Reputation: 1354
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.
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
Upvotes: 2