So I'm working on Spring Boot autoconfiguration for Axon Framework. I run into a nice interface in Axon framework that is unfortunately too specific. So I generalize. The original, pared down:
public interface AuditDataProvider { Map<String, Object> provideAuditDataFor(CommandMessage<?> command); }
Aha! A SAM interface, interesting. So I craft my look-a-like:
public interface AuditDataProvider { Map<String, Object> provideAuditDataFor(Message<?> command); }
Not much difference. Note the method parameter is Message
rather than CommandMessage
. This works fine as the implementation I have in mind uses getMetaData()
, defined in Message
and inherited by CommandMessage
—so the original Axon interface is overspecified, using a more specific parameter type than needed.
(Keep this in mind: most times use the most general type you can.)
Ah, but other parts of the Axon framework ask for an AuditDataProvider
(the original code, above) and I'm defining a new, more general interface. I cannot extend the original with mine; Java correctly complains that I am widening the type: all CommandMessage
s are Message
s, but not all Message
s are CommandMessage
s.
Java 8 method references to the rescue!
public interface MessageAuditDataProvider { Map<String, Object> provideAuditDataFor(final Message<?> message); default AuditDataProvider asAuditDataProvider() { return this::provideAuditDataFor; } }
Because I accept a supertype in my new interface relative to the original, my method reference works simply and cleanly.
No comments:
Post a Comment