How to Create a Spring Cloud Stream Binder From Scratch
Learn how to develop a custom Spring Cloud Stream binder from scratch.
Join the DZone community and get the full member experience.Join For Free
Spring Cloud Stream is a framework built on top of Spring Boot and Spring Integration that is designed to build event-driven microservices communicating via one or more shared messaging systems.
The core Spring Cloud Stream component is called “Binder,” a crucial abstraction that’s already been implemented for the most common messaging systems (e.g. Apache Kafka, Kafka Streams, Google PubSub, RabbitMQ, Azure EventHub, and Azure ServiceBus).
You may also like: Spring Cloud Stream With Kafka
In this article, we’ll see in detail how to develop a custom Spring Cloud Stream binder from scratch.
The official Spring Cloud Stream documentation already provides a very basic explanation of how to implement your own Spring Cloud Stream binder.
Here’s a brief excerpt from it about the Binder Service Provider Interface that must be implemented in order to create a custom binder:
The Binder SPI consists of a number of interfaces, out-of-the box utility classes, and discovery strategies that provide a pluggable mechanism for connecting to external middleware. The key point of the SPI is the
Binderinterface, which is a strategy for connecting inputs and outputs to external middleware. The following listing shows the definition of the
And here’s one more documentation snippet that’s basically a micro-tutorial about developing Spring Cloud Stream binders:
A typical binder implementation consists of the following: a class that implements the
Binderinterface; a Spring
@Configurationclass that creates a bean of type
Binderalong with the middleware connection infrastructure; a
META-INF/spring.bindersfile found on the classpath containing one or more binder definitions, as shown in the following example:
Even though the above documentation is quite helpful to get started, it would definitely help to have a more thoroughly detailed guide and a practical example go along with it.
TL;DR: Just Gimme the Code
If you don't have the time to go through this detailed tutorial, you can jump to my demo on GitHub, which includes a custom file-based Spring Cloud Stream binder like the one shown below and a sample application that depends on it.
Developing the Custom Binder
Let’s get our hands dirty by developing a custom Spring Cloud Stream binder that consumes events by reading files and produces events by writing to files!
Create a new Maven project with a pom.xml file similar to the following, which includes the dependency to Spring Cloud Stream:
Technically, we just need to provide our
org.springframework.cloud.stream.binder.Binder implementation, but practically, the binder depends on two more components that we need to provide first: the
ProvisioningProvider and the
ProvisioningProvider is responsible for the provisioning of consumer and producer destinations, and it is particularly useful to convert the logical destinations included in the application.yml or application.properties file in physical destination references (you could look Spring beans up by destination name, or simply trim the destination name as we do in the following snippet):
MessageProducer — unlike the name suggests — is responsible for consuming the events and handling them as messages to the client application that is configured to consume such events.
Here is an example of a
MessageProducer implementation that polls on a file that matches the trimmed destination name and is located in the project path, while also archiving read messages and discarding consequent identical messages:
Finally, with all the required components in place, we can implement our own Binder by extending the
AbstractMessageChannelBinder class, providing the required constructors and overriding the inherited abstract methods:
Last but not least, we need to provide the Spring Configuration for our binder as follows:
And the related src/main/resources/META-INF/spring.binders file with the binder name followed by the qualified name of the binder’s Spring Configuration:
Congratulations! Your custom binder implementation is now complete and can be installed in your local Maven repository by running
mvn clean install
Testing the Custom Binder
Add your custom binder dependency to the pom.xml file, in the dependencies section:
Replace the src/main/resources/application.properties file with the following application.yml file, which enables logging for all events that are managed by Spring Cloud Stream:
Replace the src/main/java/SpringCloudStreamCustomBinderDemo.java file contents with the following:
Finally, add a file named “input” to the main project directory and write something to it.
With this configuration in place, you can now launch the application by running
mvn spring-boot:run, relying on the custom Spring Cloud Stream binder we just implemented to: keep consuming events from the “input” file you just created; write the processing results to an output file named “output”; and keep track of all previously read messages in the “archive.txt” file.
The official Spring Cloud Stream reference documentation is quite helpful when it comes down to implementing your own binder but it’s definitely not enough.
That being held, creating your own binder implementation is almost effortless even though it might appear like a hard task at first; also, knowing how to build a custom Spring Cloud Stream binder makes for a quite niche and useful skill in the development field!
Moreover, knowing how Spring Cloud Stream binders work makes it easy to customize already existing ones, and not just building new binders (which, in all honesty, might be a less common scenario given most use cases).
References & Useful Resources
Published at DZone with permission of Domenico Sibilio. See the original article here.
Opinions expressed by DZone contributors are their own.