Java spring resolving dependency in a generic method

Viewed 40

I'm looking for suggestions on how to simplify some generics in Java/Spring

Let's say I have the following:

public Interface Event
{
}

public Interface EventHandler<T extends Event>
{
  void handle(T event);
}

@Component
public class SomeEvent implements Event
{
}

@Component
public class SomeEventHandler implements EventHandler<SomeEvent>
{
  public void handle(SomeEvent event)
  {
    // Some handling
  }
}

@Component
public class EventHandlers<T extends Event>
{
  private final List<EventHandler<T>> eventHandlers;

  public EventHandlers(List<EventHandler<T>> handlers)
  {
    this.handlers = handlers;
  }

  public void handle(T event)
  {
    for (var handler : handlers)
      handler.handle(event);
  }
}

The above code works well with the Spring injection framework in a manner like this:


@Component
public class SomeClass
{
  private final EventHandlers<SomeEvent> someEventHandler;
  private final EventHandlers<SomeOtherEvent> someOtherEventHandler;

  public SomeClass(EventHandlers<SomeEvent> someEventHandlers, EventHandlers<SomeOtherEvent> 
  someOtherEventHandlers)
  {
    // assign to fields;
  }

  public void SomeMethodThatSendsSomeEvent()
  {
    someEventHandlers.handle(new SomeEvent());
  }

  public void SomeMethodThatSendsSomeOtherEvent()
  {
    someOtherEventHandlers.handle(new SomeOtherEvent());
  }
}

My issue with this is that the constructor signature scales badly when the amount of needed event type increases.

What I would like to achieve is a single class that resolves the types needed (without instantiating them every time).

Something like:

@Component
public class EventHandlers
{
  public void handle<T extends Event>(T event)
  {
    // This is the problem. I need to get the correct EventHandlers<T> injected here, somehow
  }
}

@Component
public class SomeClass
{
  private final EventHandlers eventHandlers;

  public SomeClass(EventHandlers eventHandlers)
  {
    // assign to fields;
  }

  public void SomeMethodThatSendsSomeEvent()
  {
    eventHandlers.handle(new SomeEvent());
  }

  public void SomeMethodThatSendsSomeOtherEvent()
  {
    eventHandlers.handle(new SomeOtherEvent());
  }
}

Any suggestions as to how one would solve this using Java/Spring? Ideally using generics and injection only.

0 Answers
Related