Spring cloud stream gives abstractions, primitives for a simple way to develop message-driven applications.
Application Model:
Spring cloud stream contains middleware and application core. The application will communicate with the outside world using input/output channels that are introduced by the spring cloud stream.
Binder Abstraction:
Applications individually choose to which middleware they want to connect, by default spring cloud stream is dependent on spring boot auto-configuration, if more than one binder is present on the class path then, using the application.properties or application.yml we need to provide the binder configurations, we can also choose binder at channel level also, means for one channel we can use Kafka middleware and for another channel we can choose RabbitMQ channel, etc.
Persist Publish Subscribe: Communication between applications will use a publish-subscribe model where data is shared among the all connected client. The below diagram shows a typical flow between applications.
Consumer Groups:The Publish subscribe provides the ability to scale up by creating multiple instances of the application. When multiple instances of the same application running we need to consume messages by only one of the instances of the application. Spring cloud stream implements this behavior by providing the group name for consumers so that only one of the instances per group will be handled. We can specify the group name in application.properties file:
spring.cloud.stream.bindings.<channelName>.group
All the groups subscribed to groups will receive a copy of published data, but only one of the group members will receive the message from the destination when the group is not specified spring cloud stream assigns an anonymous group and independent single-member consumer group along with other consumer groups.
Durability: The applications sent to consumer group y default are durable, the binder implementations ensure that they are persistent, once at least one subscription for a group has been created, the group will receive messages, even if they are sent while all applications in the group are stopped. We must specify the group name so that no duplicate messages will be handled again.
Programming Model: We can turn the spring application into a spring cloud stream by adding @EnableBinding on one of the application configuration files, this annotation is meta-annotated with @Configuration and it triggers the annotation of spring cloud stream.
@Configuration
@Import({ChannelBindingServiceConfiguration.class,
BindingBeansRegistrar.class,
BinderFactoryConfiguration.class,
SpelExpressionConverterConfiguration.class})
@EnableIntegration
public@interfaceEnableBinding {
/**
* A list of interfaces having methods annotated with {@link Input} and/or
* {@link Output} to indicate bindable components.
*/
Class<?>[] value() default {};
}
This remark will accept one or more than one example contains methods which represent the bind methods.
Creating binding interface: Spring cloud stream application can have any number of input, output channels clarified in an interface remarked with @Input, @output, and we require to pass this interface in @EnableBinding annotation, this will trigger the spring cloud stream and creates orders,hotDrinks,coldDrinks message channels.
public interface Hotel {
@Input
SubscribableChannelorders();
@Output
MessageChannelhotDrinks();
@Output
MessageChannelcoldDrinks();
}
Customizing the Channel names: We can customize the channel name using value attribute in Input, Output annotation.
public interface Hotel {
@Input("inboundOrders")
SubscribableChannelorders();
...
}
The generated bound channel will named Inbound Orders.
Spring cloud stream provides 3 interfaces for common use cases.
Sink: It is interface used for single inbound channel.
Source: It is interface used for single outbound channel.
Processor: It is interface used for both single inbound/outbound channels. Spring cloud stream does not gives any special handling for these interfaces, they supplied only for reference.
Injecting interfaces into Spring Beans: Then methods clarified in interfaces given in @EnableBinding annotation will generate a channel based on its type (like input channel for @Input and output channel for @Output), and using methods in interfaces we can send/receive the messages.
Injecting Message Channels Directly: Instead of depending these interfaces we can also directly inject channels directly into beans.
@Component
public class SendingBean {
privateMessageChannel output;
@Autowired
publicSendingBean(MessageChannel output) {
this.output = output;
}
public void sayHello(String name) {
output.send(MessageBuilder.withPayload(body).build());
}
}
MessageChannel is injected with channel name output, we can also customize by passing channel name to MessageChannel.
Eg: @Output("customOutput")
MessageChanneloutput();
Spring cloud stream also supports spring-messaging and spring-integration annotations like @SendTo, @MessageMapping,@Transformer,@ServiceActivator etc.
Binders: Spring cloud stream gives Binder interface for connecting with various middleware suppliers.
The interface has bindProducer method to return the producer, the method has three arguments, and first argument take the channel name, and second argument is the channel instance to send the messages, third parameter points to channel extra properties.
The interface has bindConsumer method is to return the customer, the method has four arguments, first argument refers to destination name, and second argument refers to logical group name, third argument refers to channel instance to receive the message and four argument refers to extra customers properties.
public interface Binder<T, C extends ConsumerProperties, P extends ProducerProperties> {
Binding<T>bindConsumer(String name, String group, T inboundBindTarget, C consumerProperties);
Binding<T>bindProducer(String name, T outboundBindTarget, P producerProperties);
}
Specifying Properties for each channel:
We can also clarify properties for each channel like clarifying binder, binder configuration, content-type of the message, max-retries for each channel etc.
We can clarify channel properties using prefix in application.properties file.
spring.cloud.stream.bindings.<channelName>
List of properties assisted by channel specific are expose in BindingProperties.java file.
We can specify the manufacturer related properties using prefix spring.cloud.stream.bindings.
<channelName>.producer
Consumer properties using spring.cloud.stream.bindings.<channelName>.consumer prefix.
We can also specify the host details of binder using
spring.cloud.stream.binders.<binding-name>.environment.spring.rabbitmq.host property.
Conclusion: Spring cloud stream is framework for growing stream based application in an simple way, which is used to expand application in flexible way(independent applications), we can lightly hosted on spring data flow servers, we can combine with different middleware applications using native middleware support. We can also identify the global configuration and also channel specific binder properties, and also if the application is hosted on cloud using cloud connectors we can identify the cloud instances of middleware applications.
You can download the producer and consumer of the applications using below github repositories.
https://github.com/sravan4rmhyd/Spring-Stream-RabbitMQ.git
Have you tried Spring Cloud Stream for java web development yet? Share your experience with the readers and let them know about this framework.
Related Articles:
How can you become a professional Java developer in 6 months?
Boost your revenue by teaching cybersecurity skills to your staff.