I did something similar sometime ago, and I think that the implementation was nice.
Let's say that you want to have a thin and generic messageArrived method, something like this:
@Override
public void messageArrived(String topic, MqttMessage message) throws Exception {
messageHandler.getMessageHandler(topic).handle(message);
}
This is nice right? So how we can achieve something like that?
First let's define an annotation and also an interface
@Retention(RUNTIME)
@Target({TYPE})
public @interface MessageHandler {
String value()
}
public interface Handler {
void handle(MqttMessage message);
}
and now let's use this annotation in a class
@MessageHandler("myTopic")
public class MyTopicHandler implements Handler {
@override
public void handle(MqttMessage message) {
// do your somthing with the message
}
}
The last part it's to write the MessageHandler class, in this class you just need to store in a map all your handlers instances, the key of the map will be the topic name and the value and instance of the class. Basically you getMessageHandler method will look something like:
public Handler getMessageHandler(String topic) {
if (handlerMap == null) {
loadClassesFromClassPath(); // This method should load from classpath all the classes with the annotation MessageHandler and build the handlerMap
}
return handlerMap.get(topic);
}
The good thing with this solution it's that if you need to add a new handler for a new message, you just need to write the new class, add the annotation to the class and that's all. The rest of the code remains the same because it's generic and it's using reflection to load and create instances.
Hope this helps you a bit.
Hi @mario_hartman, I would like to elaborate a blog post on this topic, and of course I'd like to quote you. Do you have any blog or particular contact you would like to be linked to?