I need to build my own library to handle events coming from an event bus, the first solution I came up with was an abstract class made like this one:
public abstract class MyEventListener<T> extends RealEventListener{
private final Class<T> type; //the event class type
private final String stream; //the stream
public abstract onEvent(T type); //the method my subclasses have to implement
@Overrides
public void onEvent(byte[] evt){ //takes the original, clunky method and evolves it with typing
//convert and do stuff
onEvent(convertedEvent); //call method
}
}
so, the classes only do:
@Component
public class Child extends MyEventListener<AType>{
public Child(){
super(AType.class, "stream"); //registers
}
@Overrides
public void onMessage(AType evt){ //do stuff
}
I find this approach somewhat limiting and outdated (at least seeing the latest libraries). An example I can think of is that, this way, you are forced to handle separate events in separate classes.
So, I though of using annotations to have something like this:
@EventListener("stream") //1. you define the stream in this custom class annotation
public class Child { //so no need to extend
@ListenTo(type=AType.class) //2. you define the type on methods, this way a single class can handle more
public void onMessage(AType event, //any other param){
}
Now, for the magic behind, I though about using a startup annotation processing to retrieve the methods:
public void initialize(@EventListener List<Object> listeners) { //I inject all objects
listeners.stream().map(..).collect(..) //use reflection to get all methods annotated with @ListenTo and put them inside of map <String, Method>
eventBus.registerListener(new MyEventListener(methodMap)); //
}
Now, the listener will take somewhat the type from the original byte event and call the method:
String className = getClassFromEvent(evt);
listenerMap.get(className).invoke(evt);
According to you is this approach valid and, most importantly, efficient? Or, excluding the initialization phase, it could lead to performance problems at runtime? Of course I should make static checks at initialization to make sure that the annotated methods declare the event as parameter but it seems cleaner to me than the first one.
Aucun commentaire:
Enregistrer un commentaire