{"id":15719818,"url":"https://github.com/dorkbox/messagebus","last_synced_at":"2025-05-07T13:07:11.929Z","repository":{"id":86401078,"uuid":"37750726","full_name":"dorkbox/MessageBus","owner":"dorkbox","description":"Lightweight, extremely fast, and zero-gc message/event bus for Java 6+","archived":false,"fork":false,"pushed_at":"2023-10-11T10:16:09.000Z","size":2405,"stargazers_count":40,"open_issues_count":0,"forks_count":12,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-05-07T13:07:05.678Z","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":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dorkbox.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"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}},"created_at":"2015-06-19T23:30:01.000Z","updated_at":"2025-02-20T22:36:53.000Z","dependencies_parsed_at":null,"dependency_job_id":"ff82ffae-f689-4cbd-900e-78faf0c95a34","html_url":"https://github.com/dorkbox/MessageBus","commit_stats":null,"previous_names":[],"tags_count":22,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dorkbox%2FMessageBus","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dorkbox%2FMessageBus/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dorkbox%2FMessageBus/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dorkbox%2FMessageBus/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dorkbox","download_url":"https://codeload.github.com/dorkbox/MessageBus/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252883204,"owners_count":21819160,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":"2024-10-03T21:56:53.862Z","updated_at":"2025-05-07T13:07:11.906Z","avatar_url":"https://github.com/dorkbox.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"MessageBus\n==========\n\n###### [![Dorkbox](https://badge.dorkbox.com/dorkbox.svg \"Dorkbox\")](https://git.dorkbox.com/dorkbox/MessageBus) [![Github](https://badge.dorkbox.com/github.svg \"Github\")](https://github.com/dorkbox/MessageBus) [![Gitlab](https://badge.dorkbox.com/gitlab.svg \"Gitlab\")](https://gitlab.com/dorkbox/MessageBus)\n\n\n\nThe MessageBus is an extremely light-weight message/event bus implementation that follows the publish/subscribe pattern and is based on the [MBassador](https://github.com/bennidi/mbassador) project. It is designed for ease of use and simplicity, and aims for **maximum performance** and **zero garbage** during message publication. At the core of this project is the use of the `single writer principle` as described by Nitsan Wakart on his [blog](http://psy-lob-saw.blogspot.com/2012/12/atomiclazyset-is-performance-win-for.html) and the fantastic [LMAX Disruptor](https://github.com/LMAX-Exchange/disruptor).\n  \nUsing the MessageBus in your project is very easy.   \n  1 Create an instance of the MessageBus (usually a singleton will do) `MessageBus bus = new MessageBus()`  \n  2 Mark and configure your message subscription handlers (the methods that will receive the messages) with `@Subscribe` notations  \n  3 Register these via `bus.subscribe(listener)`  \n  4 Send messages to these listeners via `bus.publish(message)` for synchronous publication, or `bus.publishAsync(message)` for asynchronous publication  \n  5 (Optional) Free resources and threads via `bus.shutdown()` when you are finished (usually on application exit)  \n  \n  You're done! \n\n\u003e Notes\n  \nThe difference between the `sync` and `async` is that with `synchronous` publication, all of the logic and method calls occur on the same thread that calls it; while with an `asynchronous` publication, all of these actions occur on a separate thread. Please note that asynchronous publication is not in a guaranteed order.\n  \n  \n`bus.shutdown()`. It is not necessary if exiting the JVM (which is most use-cases), but it is extremely useful in situations where you are reloading classes (ie: a webserver), as it will guarantee freeing all used resources and threads.\n  \nTable of contents:\n+ [Features](#features)\n+ [Usage](#usage)\n+ [Installation](#installation)\n+ [License](#license)\n\n\u003ch2 name=\"features\"\u003eFeatures\u003c/h2\u003e\n\n\u003e Annotations\n\n|Annotation|Function|\n|:-----|:-----|\n|`@Subscribe`|Defines and customizes a message subscription handler. Any well-formed method annotated with `@Subscribe` will cause instances of the defining class to be treated as event receivers|\n|`@Listener`|Can be used to customize listener wide configuration like the used reference type|\n|`@Synchronized`|Specifies that the handler/method will be accessed in a `synchronized` block|\n\n\u003e Delivers everything\n\nMessages do not need to implement any interface and can be of any type. It is possible though to define an upper bound of the message type using generics. The class hierarchy of a message is considered during message delivery, such that handlers will also receive subtypes of the message type they consume for - e.g. a handler of Object.class receives everything. Messages that do not match any handler result in the publication of a `DeadMessage` object which wraps the original message. DeadMessage events can be handled by registering listeners that handle DeadMessage.\n\n\u003e Configurable reference types\n\nBy default, the MessageBus uses strong references for listeners. If the programmer wants to relieve the  need to explicitly unsubscribe listeners that are not used anymore and avoid memory-leaks, it is trivial to configure via setting the `SubscriptionMode`. Using strong references is the fastest, most robust method for dispatching messages, however weak references are very comfortable in container managed environments where listeners are created and destroyed by frameworks, i.e. Spring, Guice etc. Just stuff everything into the message bus, it will ignore objects without message handlers and automatically clean-up orphaned weak references after the garbage collector has done its job. Strongly referenced listeners will stick around until explicitly unsubscribed.\n\n\u003e Custom error handling\n\nErrors during message delivery are sent to all registered error handlers which can be added to the bus as necessary.\n\n\n\u003ch2\u003eUsage\u003c/h2\u003e\n\nHandler definition (in any bean):\n\n        // every message of type TestMessage or any subtype will be delivered to this subscription handler\n        @Subscribe\n\t\tpublic void handleTestMessage(TestMessage message) {\n\t\t\t// do something\n\t\t}\n\n\t\t// every message of type TestMessage or any subtype will be delivered to this subscription handler\n        @Subscribe\n        public void handleTestMessage(TestMessage message) {\n            // do something\n        }\n\n        // this subscription handler will not accept subtypes of the TestMessage.\n        @Subscribe(acceptSubtypes = false})\n        public void handleNoSubTypes(TestMessage message) {\n           //do something\n        }\n\n        // this handler will be accessed in a \"syncrhonized\" manner (only one thread at a time may access it)\n        @Subscribe\n        @Synchronized\n        public void handleSynchronzied(TeastMessage message) {\n            //do something\n        }\n\n        // configure a listener to be stored using strong/weak references\n        @Listener(references = References.Strong)\n        public class MessageListener{\n            @Subscribe\n            public void handleTestMessage(TestMessage message) {\n                // do something\n            }\n        }\n\n\nCreation of message bus and registration of listeners:\n\n        // create as many instances as necessary (usually a singleton is best)\n        MessageBus bus = new MessageBus();\n        \n        ListeningBean listener = new ListeningBean();\n        \n        // the listener will be registered using a weak-reference if not configured otherwise via @Listener\n        bus.subscribe(listener);\n        \n        // this listener without handlers will be ignored\n        bus.subscribe(new ClassWithoutAnyDefinedHandlers());\n        \n        // do stuff....\n        \n        \n        // and when FINSIHED with the messagebus, to shutdown all of the in-use threads and clean the data-structures\n        bus.shutdown();\n        \n\n\nMessage publication:\n\n        TestMessage message = new TestMessage();\n        TestMessage message2 = new TestMessage();\n        TestMessage message3 = new TestMessage();\n        TestMessage subMessage = new SubTestMessage();\n\n        bus.publishAsync(message); // returns immediately, publication will continue asynchronously\n        bus.publish(subMessage);   // will return after all the handlers have been invoked\n        \n        bus.publish(message, message2);   // will return after all the handlers have been invoked, but for two messages at the same time\n        bus.publish(message, message2, message3);   // will return after all the handlers have been invoked, but for three messages \n\n\n\u0026nbsp; \n\u0026nbsp; \n\nRelease Notes \n---------\n  \n  \nMaven Info\n---------\n```\n\u003cdependencies\u003e\n    ...\n    \u003cdependency\u003e\n        \u003cgroupId\u003ecom.dorkbox\u003c/groupId\u003e\n        \u003cartifactId\u003eMessageBus\u003c/artifactId\u003e\n        \u003cversion\u003e2.7\u003c/version\u003e\n    \u003c/dependency\u003e\n\u003c/dependencies\u003e\n```\n\nGradle Info\n---------\n```\ndependencies {\n    ...\n    implementation(\"com.dorkbox:MessageBus:2.7\")\n}\n```\n\nLicense\n---------\nThis project is © 2012 Benjamin Diedrichsen and © 2021 dorkbox llc, and is distributed under the terms of the Apache v2.0 License. See \nfile \"LICENSE\" for further references.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdorkbox%2Fmessagebus","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdorkbox%2Fmessagebus","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdorkbox%2Fmessagebus/lists"}