My goal is to write some kind of bridge between our global event broker and Spring's ApplicationEvent system.
The message broker provides the messages in JSON format. My idea is to have an
public class ExternalApplicationEvent extends ApplicationEvent {
...
// e.g @JsonPropert private String name;
}
And then call something like
objectMapper.readValue(brokerMessage, ExternalApplicationEvent.class);
The problem is, that the ApplicationEvent
requires a source set on construction time, which should be the instance of the ExternalEventBridge
, which is for obvious reasons not part of the JSON-document.
I found, how I can add properties to the JSON, that are not part of the serialized object with @JsonAppend
, but I haven't found a solution for my direction, passing parameters to the constructor of the class.
My last idea was to use
objectMapper.readerForUpdating(new ExternalApplicationEvent(theSource)).readValue(message)
but somehow this didn't fill my event.
If I add the constructor
public ExternalApplicationEvent() {
super(new Object());
}
and use objectMapper.readValue(message, ExternalApplicationEvent.class)
, the object is properly populated via field injection. Also adding Setters won't help.
I solved it now, by seperating the Data from the ApplicationEvent like this:
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonAutoDetect(getterVisibility = JsonAutoDetect.Visibility.NONE) // Don't detect `getSource` from ApplicationEvent
public class ExternalApplicationEvent extends ApplicationEvent {
// I might use @JsonUnwrapped probably, but since I have to create setters
// and getters anyway...
private ExternalApplicationEventData p = new ExternalApplicationEventData();
public ExternalApplicationEvent(Object source, ExternalApplicationEventData data) {
super(source);
p = data;
}
@JsonGetter("name")
public String getName() { return p.name; }
public void setName(String name) { p.name = name; }
public static class ExternalApplicationEventData {
@JsonCreator
private ExternalApplicationEventData() {} // Make creation only possible by parsing or from the ExternalApplicationEvent class
@JsonProperty
private String name;
...
}
}
And then creating the Event
var data = objectMapper.readValue(message, ExternalApplicationEvent.ExternalApplicationEventData.class);
var event = new ExternalApplicationEvent(this, data);