JacksonConfig.java
package com.wilzwert.myjobs.infrastructure.serialization.jackson;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.wilzwert.myjobs.core.domain.shared.event.integration.IntegrationEvent;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.List;
/**
* @author Wilhelm Zwertvaegher
* Domain integration events are stored as json payloads in mongodb
* We need some custom logic to deserialize this json representation into concrete integration events
* For now we are using json with jackson
*/
@Configuration
public class JacksonConfig {
/**
* List of custom deserializers implementing {@link JacksonIntegrationEventDeserializer}
* The list is automatically built by Spring because all deserializer MUST be beans (@Component)
* Then we inject the list in this config class to register the deserializers and add them to jackson
*/
private final List<JacksonIntegrationEventDeserializer<? extends IntegrationEvent>> deserializers;
public JacksonConfig(List<JacksonIntegrationEventDeserializer<? extends IntegrationEvent>> deserializers) {
this.deserializers = deserializers;
}
private <T extends IntegrationEvent> void registerDeserializer(SimpleModule module, JacksonIntegrationEventDeserializer<T> deserializer) {
Class<T> clazz = deserializer.getEventClass();
module.addDeserializer(clazz, deserializer);
}
@Bean
public Jackson2ObjectMapperBuilderCustomizer customJackson() {
return builder -> {
SimpleModule module = new SimpleModule();
for (JacksonIntegrationEventDeserializer<? extends IntegrationEvent> deserializer : deserializers) {
Class<? extends IntegrationEvent> targetClass = deserializer.getEventClass();
if (targetClass == null) {
throw new IllegalStateException("handledType == null for " + deserializer);
}
registerDeserializer(module, deserializer);
}
builder.modulesToInstall(module);
};
}
}