The module io.github.mmm.event
(artifactId mmm-event
) provides a generic event infrastructure. Sending and receiving events is a very common things.
This module implements eventing as a generic pattern and provides a simple but powerful API and base implementation that saves you from a lot of work.
It is designed minimalistic and has no external dependencies.
This library offers the following features:
-
Highly optimized
e.g. if you want to create many objects that can have event listeners. Maybe lots of them do not have any listener registered. Hence, they shall not allocate expensive
List
instances and sending events should be a no-op. -
Highly customizable
Any object can be an event. You are free to create your own custom event or send existing types (e.g.
String
) as event. You create your own custom event listener interface and simply derive it from theEventListener<E>
interface from this library, where you bind<E>
to your custom event. See examples below for further details. -
Prevent Memory Leaks
You may create objects that have an event listener registered to some event source. Now, the event source typically holds a strong reference to that listener preventing it from being garbage collected. So if you do not remove the listener when the owning object is disposed, you quickly end up with memory leaks. This library allows to add an event listener such that internally a
WeakReference
is used preventing memory leaks without additional programming effort. -
Single and Multi-Threaded
The library provides implementations optimized for different usage scenarios. You may have a simple single-threaded use-case where you want the best performance with no overhead or you may need concurrency and thread-safeness.
-
Event Bus
For eventing between loosely coupled components you may want to use the
EventBus
that acts as a central hub where listeners are registered and events are send. This way a component only needs to subscribe for a particular type of event without knowing who the sender(s) of such events actually are.
Maven Dependency:
<dependency>
<groupId>io.github.m-m-m</groupId>
<artifactId>mmm-event</artifactId>
</dependency>
Module Dependency:
requires transitive io.github.mmm.event;
Create your event as interface, class, or enum:
public class MyEvent {
private final String message;
public MyEvent(String message) {
this.message = message;
}
public String getMessage() {
return this.message;
}
}
Create your event listener interface:
@FunctionalInterface
public interface MyEventListener extends EventListener<MyEvent> {
}
Create your component capable to send events:
public interface MyComponent extends EventSource<MyEvent, MyEventListener> {
void doSomething();
}
public class MyComponentImpl extends AbstractEventSource<MyEvent, MyEventListener> implements MyComponent {
public void doSomething() {
fireEvent(new MyEvent("Hello World"));
}
}
Putting it all together:
public class MyDemo {
public static void main(String[] args) {
MyComponent component = new MyComponentImpl();
component.addListener((e) -> System.out.println(e.getMessage()));
component.doSomething();
}
}