{"id":44689628,"url":"https://github.com/Lenni0451/LambdaEvents","last_synced_at":"2026-02-27T19:01:14.953Z","repository":{"id":130805204,"uuid":"410966263","full_name":"Lenni0451/LambdaEvents","owner":"Lenni0451","description":"Fast and modular event library for Java","archived":false,"fork":false,"pushed_at":"2026-01-29T19:50:18.000Z","size":597,"stargazers_count":22,"open_issues_count":0,"forks_count":2,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-02-01T22:29:50.880Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Lenni0451.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"buy_me_a_coffee":"lv0nrncj3m","custom":["https://lenni0451.net/donate"]}},"created_at":"2021-09-27T16:45:52.000Z","updated_at":"2026-01-29T19:50:15.000Z","dependencies_parsed_at":"2023-11-10T20:24:08.561Z","dependency_job_id":"aa1cb39e-aa62-4c8d-a90d-730f1dd709f6","html_url":"https://github.com/Lenni0451/LambdaEvents","commit_stats":null,"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/Lenni0451/LambdaEvents","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Lenni0451%2FLambdaEvents","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Lenni0451%2FLambdaEvents/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Lenni0451%2FLambdaEvents/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Lenni0451%2FLambdaEvents/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Lenni0451","download_url":"https://codeload.github.com/Lenni0451/LambdaEvents/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Lenni0451%2FLambdaEvents/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29909252,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-27T17:28:36.873Z","status":"ssl_error","status_checked_at":"2026-02-27T17:28:20.970Z","response_time":57,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-02-15T07:00:30.133Z","updated_at":"2026-02-27T19:01:14.947Z","avatar_url":"https://github.com/Lenni0451.png","language":"Java","funding_links":["https://buymeacoffee.com/lv0nrncj3m","https://lenni0451.net/donate"],"categories":["进程间通信"],"sub_categories":["Spring Cloud框架"],"readme":"# LambdaEvents\nFast and modular event library for Java.\n\n- [LambdaEvents](#lambdaevents)\n  - [Releases](#releases)\n    - [Gradle Template](#gradle-template)\n    - [Maven Template](#maven-template)\n    - [Jar File](#jar-file)\n  - [Usage](#usage)\n    - [LambdaManager](#lambdamanager)\n    - [Generator](#generator)\n    - [Events](#events)\n    - [Registering](#registering)\n      - [Static event handler](#static-event-handler)\n      - [Virtual event handler](#virtual-event-handler)\n      - [Independent event handler](#independent-event-handler)\n    - [Unregistering](#unregistering)\n    - [Calling](#calling)\n    - [Priority](#priority)\n    - [Cancelling](#cancelling)\n      - [Events](#events-1)\n      - [Call chain](#call-chain)\n    - [Exception handling](#exception-handling)\n      - [Registration](#registration)\n      - [Calling](#calling-1)\n    - [Event Filter](#event-filter)\n  - [JMH Benchmark](#jmh-benchmark)\n\n\n## Releases\nTo use LambdaEvents with Gradle/Maven you can follow the instructions on [maven central](https://mvnrepository.com/artifact/net.lenni0451/LambdaEvents) or my [maven server](https://maven.lenni0451.net/#/releases/net/lenni0451/LambdaEvents).\n### Gradle Template\n```groovy\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation \"net.lenni0451:LambdaEvents:x.x.x\"\n}\n```\n### Maven Template\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003enet.lenni0451\u003c/groupId\u003e\n    \u003cartifactId\u003eLambdaEvents\u003c/artifactId\u003e\n    \u003cversion\u003ex.x.x\u003c/version\u003e\n\u003c/dependency\u003e\n```\nYou should check [maven central](https://mvnrepository.com/artifact/net.lenni0451/LambdaEvents) or my [maven server](https://maven.lenni0451.net/#/releases/net/lenni0451/LambdaEvents) for the latest version.\n\n### Jar File\nYou can download the jar file from my [Jenkins server](https://build.lenni0451.net/job/LambdaEvents/).\\\nSince LambdaEvents has no dependencies you don't need to download any other jar files.\n\n## Usage\n### LambdaManager\nTo use LambdaEvents you need to create an instance of the `LambdaManager` class.\\\nIt is the main class of the library used to register and call events.\n```java\nLambdaManager eventManager = LambdaManager.basic(generator);\n```\nOr for a thread safe version:\n```java\nLambdaManager eventManager = LambdaManager.threadSafe(generator);\n```\nThere is no global instance to prevent event conflicts.\n\n### Generator\nBecause of the dynamic nature of LambdaEvents you need to provide an `IGenerator` implementation.\\\nIt is used to generate the caller which calls the event listener.\\\nThe following implementations are provided:\n - ReflectionGenerator\n - MethodHandleGenerator\n - LambdaMetaFactoryGenerator\n - ASMGenerator (Requires [Reflect](https://github.com/Lenni0451/Reflect) and [ASM](https://mvnrepository.com/artifact/org.ow2.asm/asm))\n\nCheck out the [JMH Benchmark](#jmh-benchmark) section for performance comparisons.\n\nThe `MethodHandleGenerator` and the `LambdaMetaFactoryGenerator` have an optional `MethodHandles.Lookup` parameter.\n\nTo create your own implementation you need to implement the `IGenerator` interface.\\\nThe `generate` method is used to generate a caller for handler which take the event as a parameter.\\\nThe `generateVirtual` method is used to generate a caller for handler which don't take the event as a parameter.\n\n### Events\nIn LambdaEvents there is no need to implement an interface or extend a class to create an event.\\\nYou can pass any object as an event. Remember that the class is used to identify the event type. Inheritance is not checked and treated as a different event type.\n\n### Registering\nLambdaEvents has 6 different ways to listen to events:\n\n| Type                    | Description                                                |\n| ----------------------- | ---------------------------------------------------------- |\n| Static methods          | A static method annotated with `@EventHandler`             |\n| Virtual methods         | A virtual/non-static method annotated with `@EventHandler` |\n| (static) Runnable field | A runnable field annotated with `@EventHandler`            |\n| (static) Consumer field | A consumer field annotated with `@EventHandler`            |\n| Independent Runnable    | A runnable which is passed to the `register` method        |\n| Independent Consumer    | A consumer which is passed to the `register` method        |\n\nAll `register`/`unregister` methods have an optional `event class` parameter to specify the type of the event to register/unregister.\\\nThis parameter is required when registering an independent event handler.\n\nRunnable fields or Consumer fields without type parameters require the event type(s) to be added to the `@EventHandler(events = {Event.class})` annotation.\\\nMethods are required to not have any parameters or to have the event type as a parameter. Methods without parameters require the event type(s) to be added to the `@EventHandler(events = {Event.class})` annotation.\\\nIndependent Runnables or Consumers require the event type(s) to be passed to the `register` method.\n#### Static event handler\nTo register static event handler (methods and fields) you need to call the `register` method of the `LambdaManager` instance passing the owner class.\n```java\neventManager.register(Example.class);\n```\n#### Virtual event handler\nTo register virtual event handler (methods and fields) you need to call the `register` method of the `LambdaManager` instance passing the owner object.\n```java\neventManager.register(new Example());\n```\n#### Independent event handler\nTo register independent event handler (runnables and consumers) you need to call the `register` method of the `LambdaManager` instance passing the handler, priority and event type(s).\n```java\n//Runnable\nRunnable handler = () -\u003e System.out.println(\"called\");\neventManager.register(handler, 0, Event.class);\n\n//Consumer\nConsumer\u003cEvent\u003e handler = e -\u003e System.out.println(\"called \" + e);\neventManager.register(handler, 0, Event.class);\n```\n\n### Unregistering\nTo unregister event handler you have to call the respective `unregister` method of the `LambdaManager` instance in the same way you registered them.\n```java\n//Static\neventManager.unregister(Example.class);\n\n//Virtual\neventManager.unregister(oldExampleInstance);\n\n//Independent\neventManager.unregister(handler, Event.class);\n```\n\nYou can also unregister all event handlers for a specific event type by calling the `unregisterAll` method.\n```java\n//Unregister all event handlers for the event type\n//This includes static and virtual event handlers\neventManager.unregisterAll(Event.class);\n\n//Unregister all event handler for the event type and the given class predicate\n//In this case all handlers which extend AbstractVirtualHandler are unregistered\n//This includes static and virtual event handlers\neventManager.unregisterAll(Event.class, AbstractVirtualHandler.class::isAssignableFrom);\n\n//The unregisterAll method also has an optional boolean to only unregister static/virtual event handlers\neventManager.unregisterAll(event, predicate, true /*static*/);\n```\n\n### Calling\nTo call an event you need to call the `call` method of the `LambdaManager` instance passing the event object.\n```java\neventManager.call(new Event());\n```\n\n### Priority\nLambdaEvents supports priorities for event handlers which is used to determine the execution order.\\\nThe higher the priority is, the earlier the event handler is called.\n\n### Cancelling\n#### Events\nSince there is no requirement for an event to implement an interface or extend a class you have to implement the cancellation yourself.\\\nEven though it's not a requirement, it is recommended to implement the `ICancellableEvent` interface.\\\nExample:\n```java\npublic class Event implements ICancellableEvent {\n    private boolean cancelled = false;\n\n    public boolean isCancelled() {\n        return this.cancelled;\n    }\n\n    public void setCancelled(final boolean cancelled) {\n        this.cancelled = cancelled;\n    }\n}\n\npublic class Caller {\n    public static void callEvent(final LambdaManager eventManager) {\n        Event event = eventManager.call(new Event());\n        if (event.isCancelled()) {\n            return;\n        }\n        //Continue the method\n        //...\n    }\n}\n```\nThe `ICancellableEvent` interface is used for determining if an event handler should handle a cancelled event.\\\nThe handler can specify this by adding `handleCancelled` (default true) to the `@EventHandler` annotation.\\\nExample:\n```java\npublic class Handler {\n    @EventHandler\n    public void handleEvent(final Event event) {\n        //This handler will be called even if the event is cancelled\n    }\n\n    @EventHandler(handleCancelled = false)\n    public void handleEvent(final Event event) {\n        //This handler will not be called if the event is cancelled\n    }\n}\n```\n#### Call chain\nTo cancel the event call chain and prevent following event handlers from being executed you can throw the `StopCall.INSTANCE` exception.\n\n### Exception handling\n#### Registration\nIf an exception is thrown during the registration process, the exception will be thrown to the caller.\n#### Calling\nIf an exception is thrown by an event handler, the `ExceptionHandler` of the `LambdaManager` instance will be called.\\\nIt receives the handler, the event and the thrown exception as parameters.\\\nBy default the `ExceptionHandler` will print the stack trace of the exception to the console (`System.err`).\n\n### Event Filter\nTo make sure the `LambdaManager` only registers only the correct event types you can use the `IEventFilter`.\\\nIt is called with the event type and a type from where the filter was called.\\\nThe filter can return `true` to allow the registration/calling of the event or `false` to skip it. An exception can be thrown to notify the caller that the event type is not allowed.\\\nCheck types:\n| Type              | Description                                                                                             |\n| ----------------- | ------------------------------------------------------------------------------------------------------- |\n| CALL              | The filter was called from the `call` or the `callParents` method                                       |\n| REGISTER          | The filter was called from the `register` method without an explicit event type (wildcard registration) |\n| EXPLICIT_REGISTER | The filter was called from the `register` method with an explicitly specified event type                |\n\nThe `unregister` method does not call the filter.\\\nExample filter:\n```java\npublic boolean check(final Class event, final CheckType checkType) {\n    if (event instanceof EventBase) return true;\n    if (CheckType.CALL.equals(checkType)) throw new IllegalArgumentException();\n    if (CheckType.EXPLICIT_REGISTER.equals(checkType)) throw new IllegalArgumentException();\n    return false;\n}\n```\nThis filter will allow any event which extends `EventBase`.\\\nIf an invalid event is passed to the `call` method an `IllegalArgumentException` will be thrown.\\\nIf an event is registered explicitly an `IllegalArgumentException` will be thrown.\\\nAny other event will be blocked without throwing an exception (silent block).\n\n## JMH Benchmark\nThe Benchmark shows the average time it takes to call an event 100_000 times.\\\nThe lower the time is, the better the call performance of the generator is.\\\nThe tests were run using Java 17 and may vary on other Java versions.\n\n| Benchmark                           | Mode | Cnt | Score       | Error      | Units |\n| ----------------------------------- | ---- | --- | ----------- | ---------- | ----- |\n| CallBenchmark.callASM               | avgt | 4   | 1253339,286 | 81976,516  | ns/op |\n| CallBenchmark.callLambdaMetaFactory | avgt | 4   | 1270657,312 | 133794,400 | ns/op |\n| CallBenchmark.callMethodHandles     | avgt | 4   | 1893870,724 | 569223,318 | ns/op |\n| CallBenchmark.callReflection        | avgt | 4   | 1466385,654 | 256169,146 | ns/op |\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FLenni0451%2FLambdaEvents","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FLenni0451%2FLambdaEvents","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FLenni0451%2FLambdaEvents/lists"}