LmCast :: Stay tuned in

Emissary, a fast open-source Java messaging library

Recorded: Jan. 26, 2026, 3 p.m.

Original Summarized

GitHub - joel-jeremy/emissary: Emissary is simple, yet 🗲FAST🗲 messaging library for decoupling messages (requests and events) and message handlers 🚀

Skip to content

Navigation Menu

Toggle navigation

Sign in

Appearance settings

PlatformAI CODE CREATIONGitHub CopilotWrite better code with AIGitHub SparkBuild and deploy intelligent appsGitHub ModelsManage and compare promptsMCP RegistryNewIntegrate external toolsDEVELOPER WORKFLOWSActionsAutomate any workflowCodespacesInstant dev environmentsIssuesPlan and track workCode ReviewManage code changesAPPLICATION SECURITYGitHub Advanced SecurityFind and fix vulnerabilitiesCode securitySecure your code as you buildSecret protectionStop leaks before they startEXPLOREWhy GitHubDocumentationBlogChangelogMarketplaceView all featuresSolutionsBY COMPANY SIZEEnterprisesSmall and medium teamsStartupsNonprofitsBY USE CASEApp ModernizationDevSecOpsDevOpsCI/CDView all use casesBY INDUSTRYHealthcareFinancial servicesManufacturingGovernmentView all industriesView all solutionsResourcesEXPLORE BY TOPICAISoftware DevelopmentDevOpsSecurityView all topicsEXPLORE BY TYPECustomer storiesEvents & webinarsEbooks & reportsBusiness insightsGitHub SkillsSUPPORT & SERVICESDocumentationCustomer supportCommunity forumTrust centerPartnersOpen SourceCOMMUNITYGitHub SponsorsFund open source developersPROGRAMSSecurity LabMaintainer CommunityAcceleratorArchive ProgramREPOSITORIESTopicsTrendingCollectionsEnterpriseENTERPRISE SOLUTIONSEnterprise platformAI-powered developer platformAVAILABLE ADD-ONSGitHub Advanced SecurityEnterprise-grade security featuresCopilot for BusinessEnterprise-grade AI featuresPremium SupportEnterprise-grade 24/7 supportPricing

Search or jump to...

Search code, repositories, users, issues, pull requests...

Search

Clear

Search syntax tips

Provide feedback


We read every piece of feedback, and take your input very seriously.

Include my email address so I can be contacted

Cancel

Submit feedback

Saved searches

Use saved searches to filter your results more quickly

Name

Query

To see all available qualifiers, see our documentation.

Cancel

Create saved search

Sign in

Sign up

Appearance settings

Resetting focus

You signed in with another tab or window. Reload to refresh your session.
You signed out in another tab or window. Reload to refresh your session.
You switched accounts on another tab or window. Reload to refresh your session.

Dismiss alert

joel-jeremy

/

emissary

Public

Uh oh!

There was an error while loading. Please reload this page.


Notifications
You must be signed in to change notification settings

Fork
5

Star
86

Emissary is simple, yet 🗲FAST🗲 messaging library for decoupling messages (requests and events) and message handlers 🚀

License

Apache-2.0 license

86
stars

5
forks

Branches

Tags

Activity

Star

Notifications
You must be signed in to change notification settings

Code

Issues
0

Pull requests
5

Discussions

Actions

Projects
0

Security
0

Insights

Additional navigation options

Code

Issues

Pull requests

Discussions

Actions

Projects

Security

Insights

joel-jeremy/emissary

 mainBranchesTagsGo to fileCodeOpen more actions menuFolders and filesNameNameLast commit messageLast commit dateLatest commit History215 Commits.github.github  build-logicbuild-logic  emissary-coreemissary-core  gradlegradle  .gitattributes.gitattributes  .gitignore.gitignore  CONTRIBUTING.mdCONTRIBUTING.md  LICENSELICENSE  README.mdREADME.md  build.gradle.ktsbuild.gradle.kts  gradle.propertiesgradle.properties  gradlewgradlew  gradlew.batgradlew.bat  settings.gradle.ktssettings.gradle.kts  View all filesRepository files navigationREADMEContributingApache-2.0 licenseEmissary (formerly Deezpatch)

A simple-to-use, no dependency, yet 🗲BLAZING FAST🗲 messaging library for decoupling messages (requests and events) and message handlers 🚀
Emissary aims to take advantage of the simplicity of using the annotations for handlers (e.g. @RequestHandler/@EventHandler) without the drawbacks of reflection (slow).
Emissary aims to make it easy to build applications that apply the Command Query Responsibility Segregation (CQRS) pattern, but it is not in any way limited to that pattern only.
Like the project?
Please consider giving the repository a ⭐. It means a lot! Thank you :)
Get Emissary
ImportantUp until v1.1.0, the core library is published under the old deezpatch-core name. This has been renamed to emissary-core starting from v2.0.0 onwards.

Gradle
implementation "io.github.joel-jeremy.emissary:emissary-core:${version}"
Maven
<dependency>
<groupId>io.github.joel-jeremy.emissary</groupId>
<artifactId>emissary-core</artifactId>
<version>${version}</version>
</dependency>
Java 9 Module Names
ImportantUp until v1.1.0, the core library has the module name io.github.joeljeremy.deezpatch.core. This has been renamed to io.github.joeljeremy.emissary.core starting from v2.0.0 onwards.

Emissary jars are published with Automatic-Module-Name manifest attribute:

Core - io.github.joeljeremy.emissary.core

Module authors can use above module names in their module-info.java:
module foo.bar {
requires io.github.joeljeremy.emissary.core;
}
Performance
What differentiates Emissary from other messaging/dispatch libraries? It takes advantage of java.lang.invoke.LambdaMetafactory to avoid the cost of invoking methods reflectively. This results in performance close to directly invoking the request handler and event handler methods!
~ 1000% more throughput compared to other similar libraries (Spring's ApplicationEventPublisher, Pipelinr, EventBus)
~ 90% faster compared to other similar libraries (Spring's ApplicationEventPublisher, Pipelinr, EventBus)
Java 25 Benchmarks
Java 21 Benchmarks
Java 17 Benchmarks
Java 11 Benchmarks
Requests
Requests are messages that either:

Initiate a state change/mutation

Commands in CQRS

Retrieve/query data

Queries in CQRS

public class CreateFooCommand implements Request<Void> {
private final String name;

public CreateFooCommand(String name) {
this.name = name;
}

public String name() {
return name;
}
}

public class GetFooByNameQuery implements Request<Foo> {
private final String name;

public GetFooByNameQuery(String name) {
this.name = name;
}

public String name() {
return name;
}
}
Request Handlers
Requests are handled by request handlers. Request handlers can be registered through the use of the @RequestHandler annotation.
A request must only have a single request handler.
(@RequestHandlers fully support methods with void return types! No need to set method return type to Void and return null for no reason.)
public class CreateFooCommandHandler {
@RequestHandler
public void handle(CreateFooCommand command) {
insertFooToDatabase(command.name());
}
}

public class GetFooQueryHandler {
@RequestHandler
public Foo handle(GetFooByNameQuery query) {
return getFooFromDatabase(query.name());
}
}
Request Dispatcher
Requests are dispatched to a single request handler and this can be done through a dispatcher.
public static void main(String[] args) {
// Use Spring's application context as InstanceProvider in this example
// but any other DI framework can be used e.g. Guice, Dagger, etc.
ApplicationContext applicationContext = springApplicationContext();

// Emissary implements the Dispatcher interface.
Dispatcher dispatcher = Emissary.builder()
.instanceProvider(applicationContext::getBean)
.requests(config -> config.handlers(CreateFooCommandHandler.class, GetFooQueryHandler.class))
.build();

// Send command!
dispatcher.send(new CreateFooCommand("Emissary"));

// Send query!
Optional<Pong> pong = dispatcher.send(new GetFooByNameQuery("Emissary"));
}
Events
Events are messages that indicate that something has occurred in the system.
public class FooCreatedEvent implements Event {
private final String name;

public FooCreatedEvent(String name) {
this.name = name;
}

public String name() {
return name;
}
}
Event Handlers
Events are handled by event handlers. Event handlers can be registered through the use of the @EventHandler annotation.
An event can have zero or more event handlers.
public class FooEventHandler {
@EventHandler
public void notifyA(FooCreatedEvent event) {
helloFoo(event.name());
}

@EventHandler
public void notifyB(FooCreatedEvent event) {
kumustaFoo(event.name());
}
}
Event Publisher
Events are dispatched to zero or more event handlers and this can be done through a publisher.
public static void main(String[] args) {
// Use Spring's application context as InstanceProvider in this example
// but any other DI framework can be used e.g. Guice, Dagger, etc.
ApplicationContext applicationContext = springApplicationContext();

// Emissary implements the Publisher interface.
Publisher publisher = Emissary.builder()
.instanceProvider(applicationContext::getBean)
.events(config -> config.handlers(FooEventHandler.class))
.build();

// Publish event!
publisher.publish(new FooCreatedEvent("Emissary"));
}
Easy Integration with Dependency Injection (DI) Frameworks
The library provides an InstanceProvider interface as an extension point to let users customize how request/event handler instances should be instantiated. This can be as simple as new-ing up request/event handlers or getting instances from a DI framework such as Spring's ApplicationContext, Guice's Injector, etc.
Example with No DI framework
// Application.java

public static void main(String[] args) {
Emissary emissary = Emissary.builder()
.instanceProvider(Application::getInstance)
.requests(...)
.events(...)
.build();
}

private static Object getInstance(Class<?> handlerType) {
if (MyRequestHandler.class.equals(handlerType)) {
return new MyRequestHandler();
} else if (MyEventHandler.class.equals(handlerType)) {
return new MyEventHandler();
}

throw new IllegalStateException("Failed to get instance for " + handlerType.getName() + ".");
}
Example with Spring's ApplicationContext
public static void main(String[] args) {
ApplicationContext applicationContext = springApplicationContext();
Emissary emissary = Emissary.builder()
.instanceProvider(applicationContext::getBean)
.requests(...)
.events(...)
.build();
}
Example with Guice's Injector
public static void main(String[] args) {
Injector injector = guiceInjector();
Emissary emissary = Emissary.builder()
.instanceProvider(injector::getInstance)
.requests(...)
.events(...)
.build();
}
Custom Request/Event Handler Annotations
In cases where a project is built in such a way that bringing in external dependencies is considered a bad practice (e.g. domain layer/package in a Hexagonal (Ports and Adapters) architecture), Emissary provides a way to use custom request/event handler annotations (in addition to the built-in RequestHandler and EventHandler annotations) to annotate request/event handlers.
This way, Emissary can still be used without adding the core Emissary library as a dependency of a project's domain layer/package. Instead, it may be used in the outer layers/packages to wire things up.
// Let's say below classes are declared in a project's core/domain package:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface AwesomeRequestHandler {}

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface AwesomeEventHandler {}

public class MyRequestHandler {
@AwesomeRequestHandler
public void handle(TestRequest request) {
// Handle.
}
}

public class MyEventHandler {
@AwesomeEventHandler
public void handle(TestEvent event) {
// Handle.
}
}

// To wire things up:

public static void main(String[] args) {
// Use Spring's application context as InstanceProvider in this example
// but any other DI framework can be used e.g. Guice, Dagger, etc.
ApplicationContext applicationContext = springApplicationContext();

// Register handlers and custom annotations.
Emissary emissary = Emissary.builder()
.instanceProvider(applicationContext::getBean)
.requests(config -> config.handlerAnnotations(AwesomeRequestHandler.class).handlers(MyRequestHandler.class))
.events(config -> config.handlerAnnotations(AwesomeEventHandler.class).handlers(MyEventHandler.class))
.build();
}
Custom Invocation Strategies
The library provides Emissary.RequestHandlerInvocationStrategy and Emissary.EventHandlerInvocationStrategy interfaces as extension points to let users customize how request/event handler methods are invoked by the Dispatcher and Publisher.
Built-in implementations are:

SyncRequestHandlerInvocationStrategy (Default)
SyncEventHandlerInvocationStrategy (Default)
AsyncEventHandlerInvocationStrategy

Users can create a new implementation and override the defaults by:
// Register custom invocation strategy.
Emissary emissary = Emissary.builder()
.requests(config -> config.invocationStrategy(new CustomRetryOnErrorInvocationStrategy()))
.events(config -> config.invocationStrategy(new CustomOrderGuaranteedInvocationStrategy()))
.build();

About

Emissary is simple, yet 🗲FAST🗲 messaging library for decoupling messages (requests and events) and message handlers 🚀

Topics

java

jvm

messaging

event

publisher

eventbus

requests

dispatcher

Resources

Readme

License

Apache-2.0 license

Contributing

Contributing

Uh oh!

There was an error while loading. Please reload this page.


Activity
Stars

86
stars
Watchers

2
watching
Forks

5
forks

Report repository

Releases
4

2.0.0

Latest

Jan 14, 2026


+ 3 releases

Sponsor this project

 

Uh oh!

There was an error while loading. Please reload this page.



buymeacoffee.com/joeljeremy

https://www.paypal.me/joeljeremymarquez

Learn more about GitHub Sponsors

Packages
0

 

 

 

Uh oh!

There was an error while loading. Please reload this page.


Uh oh!

There was an error while loading. Please reload this page.


Contributors
4

joel-jeremy
Joel Jeremy Marquez

dependabot[bot]

github-actions[bot]

tedyoung
Ted M. Young

Languages

Java
99.7%

Kotlin
0.3%

Footer

© 2026 GitHub, Inc.

Footer navigation

Terms

Privacy

Security

Status

Community

Docs

Contact

Manage cookies

Do not share my personal information

You can’t perform that action at this time.

Emissary is a remarkably efficient messaging library designed for decoupling requests and events, providing a streamlined approach to CQRS patterns without the drawbacks of reflection-based solutions. Developed by Joel Jeremy Marquez, Emissary aims to deliver blazing-fast performance through the strategic utilization of Java's `LambdaMetafactory` to bypass the overhead associated with traditional reflective invocation. This allows Emissary to achieve throughput and speed approaching direct method calls, resulting in performance improvements of approximately 1000% compared to libraries such as Spring's ApplicationEventPublisher and Pipelinr, with reductions of approximately 90% in latency compared to those same libraries.

The library's core philosophy centers around simplicity and ease of integration. It avoids the complexity introduced by reflection while still offering powerful features for managing requests and events. Emissary employs annotations – `@RequestHandler` and `@EventHandler` – to clearly define handlers, and it supports methods with `Void` return types, simplifying the coding process and preventing the unnecessary use of `null`. The library provides `Dispatcher` and `Publisher` interfaces for managing message dispatch and event propagation, offering flexibility in how requests and events are handled.

Emissary’s architecture is built around the concept of an InstanceProvider, providing a customizable point to manage the instantiation of request and event handlers. This accommodates a variety of dependency injection frameworks, including Spring, Guice, and Dagger, allowing seamless integration into diverse project landscapes. Importantly, Emissary incorporates custom annotations, `@AwesomeRequestHandler` and `@AwesomeEventHandler`, offering greater control for projects adhering to architectural patterns like Hexagonal (Ports and Adapters).

The library's design emphasizes performance and efficiency. The use of `LambdaMetafactory` directly addresses the inherent performance limitations of reflection, resulting in the dramatic gains observed in speed and throughput. Moreover, Emissary offers extension points through interfaces like `RequestHandlerInvocationStrategy` and `EventHandlerInvocationStrategy` enabling customization of invocation approaches. The inclusion of built-in support for various dependency injection frameworks and the customizable InstanceProvider solidify Emissary's versatility and adaptability. The library's simple and well-documented approach contributes to ease of adoption and reduced development time, a particularly valuable consideration for applications that demand high performance and scalable messaging.