Partner – Microsoft – NPI (cat= Spring Boot)
announcement - icon

Azure Spring Apps is a fully managed service from Microsoft (built in collaboration with VMware), focused on building and deploying Spring Boot applications on Azure Cloud without worrying about Kubernetes.

And, the Enterprise plan comes with some interesting features, such as commercial Spring runtime support, a 99.95% SLA and some deep discounts (up to 47%) when you are ready for production.

>> Learn more and deploy your first Spring Boot app to Azure.

You can also ask questions and leave feedback on the Azure Spring Apps GitHub page.

Course – LS – All

Get started with Spring and Spring Boot, through the Learn Spring course:


1. Overview

In this tutorial, we’ll see how to send scheduled messages from a server to the browser using WebSockets. An alternative would be using Server sent events (SSE), but we won’t be covering that in this article.

Spring provides a variety of scheduling options. First, we’ll be covering the @Scheduled annotation. Then, we’ll see an example with Flux::interval method provided by Project Reactor. This library is available out-of-the-box for Webflux applications, and it can be used as a standalone library in any Java project.

Also, more advanced mechanisms exist, like the Quartz scheduler, but we won’t be covering them.

2. A Simple Chat Application

In a previous article, we used WebSockets to build a chat application. Let’s extend it with a new feature: chatbots. Those bots are the server-side components that push scheduled messages to the browser.

2.1. Maven Dependencies

Let’s start by setting the necessary dependencies in Maven. To build this project, our pom.xml should have:


2.2. JavaFaker Dependency

We’ll be using the JavaFaker library to generate our bots’ messages. This library is often used to generate test data. Here, we’ll add a guest named “Chuck Norris” to our chat room.

Let’s see the code:

Faker faker = new Faker();
ChuckNorris chuckNorris = faker.chuckNorris();
String messageFromChuck = chuckNorris.fact();

The Faker will provide factory methods for various data generators. We’ll be using the ChuckNorris generator. A call to chuckNorris.fact() will display a random sentence from a list of predefined messages.

2.3. Data Model

The chat application uses a simple POJO as the message wrapper:

public class OutputMessage {

    private String from;
    private String text;
    private String time;

   // standard constructors, getters/setters, equals and hashcode

Putting it all together, here’s an example of how we create a chat message:

OutputMessage message = new OutputMessage(
  "Chatbot 1", "Hello there!", new SimpleDateFormat("HH:mm").format(new Date())));

2.4. Client-Side

Our chat client is a simple HTML page. It uses a SockJS client and the STOMP message protocol.

Let’s see how the client subscribes to a topic:

    <script src="./js/sockjs-0.3.4.js"></script>
    <script src="./js/stomp.js"></script>
    <script type="text/javascript">
        // ...
        stompClient = Stomp.over(socket);
        stompClient.connect({}, function(frame) {
            // ...
            stompClient.subscribe('/topic/pushmessages', function(messageOutput) {
        // ...
<!-- ... -->

First, we created a Stomp client over the SockJS protocol. Then, the topic subscription serves as the communication channel between the server and the connected clients.

In our repository, this code is in webapp/bots.html. We access it when running locally at http://localhost:8080/bots.html. Of course, we need to adjust the host and port depending on how we deploy the application.

2.5. Server-Side

We’ve seen how to configure WebSockets in Spring in a previous article. Let’s modify that configuration a little bit:

public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

    public void configureMessageBroker(MessageBrokerRegistry config) {

    public void registerStompEndpoints(StompEndpointRegistry registry) {
        // ...

To push our messages, we use the utility class SimpMessagingTemplate. By default, it’s made available as a @Bean in the Spring Context. We can see how it’s declared through autoconfiguration when the AbstractMessageBrokerConfiguration is in the classpath. Therefore, we can inject it into any Spring component.

Following that, we use it to publish messages to the topic /topic/pushmessages. We assume our class has that bean injected in a variable named simpMessagingTemplate:

  new OutputMessage("Chuck Norris", faker.chuckNorris().fact(), time));

As shown previously in our client-side example, the client subscribes to that topic to process messages as they arrive.

3. Scheduling Push Messages

In the Spring ecosystem, we can choose from a variety of scheduling methods. If we use Spring MVC, the @Scheduled annotation comes as a natural choice for its simplicity. If we use Spring Webflux, we can also use Project Reactor’s Flux::interval method. We’ll see one example of each.

3.1. Configuration

Our chatbots will use the JavaFaker’s Chuck Norris generator. We’ll configure it as a bean so we can inject it where we need it.

class AppConfig {

    public ChuckNorris chuckNorris() {
        return (new Faker()).chuckNorris();

3.2. Using @Scheduled

Our example bots are scheduled methods. When they run, they send our OutputMessage POJOs through a WebSocket using SimpMessagingTemplate.

As its name implies, the @Scheduled annotation allows the repeated execution of methods. With it, we can use simple rate-based scheduling or more complex “cron” expressions.

Let’s code our first chatbot:

public class ScheduledPushMessages {

    @Scheduled(fixedRate = 5000)
    public void sendMessage(SimpMessagingTemplate simpMessagingTemplate, ChuckNorris chuckNorris) {
        String time = new SimpleDateFormat("HH:mm").format(new Date());
          new OutputMessage("Chuck Norris (@Scheduled)", chuckNorris().fact(), time));

We annotate the sendMessage method with @Scheduled(fixedRate = 5000). This makes sendMessage run every five seconds. Then, we use the simpMessagingTemplate instance to send an OutputMessage to the topic. The simpMessagingTemplate and chuckNorris instances are injected from the Spring context as method parameters.

3.3. Using Flux::interval()

If we use WebFlux, we can use the Flux::interval operator. It will publish an infinite stream of Long items separated by a chosen Duration.

Now, let’s use Flux with our previous example. The goal will be to send a quote from Chuck Norris every five seconds. First, we need to implement the InitializingBean interface to subscribe to the Flux at application startup:

public class ReactiveScheduledPushMessages implements InitializingBean {

    private SimpMessagingTemplate simpMessagingTemplate;

    private ChuckNorris chuckNorris;

    public ReactiveScheduledPushMessages(SimpMessagingTemplate simpMessagingTemplate, ChuckNorris chuckNorris) {
        this.simpMessagingTemplate = simpMessagingTemplate;
        this.chuckNorris = chuckNorris;

    public void afterPropertiesSet() throws Exception {
            // discard the incoming Long, replace it by an OutputMessage
            .map((n) -> new OutputMessage("Chuck Norris (Flux::interval)", 
                              new SimpleDateFormat("HH:mm").format(new Date()))) 
            .subscribe(message -> simpMessagingTemplate.convertAndSend("/topic/pushmessages", message));

Here, we use constructor injection to set the simpMessagingTemplate and chuckNorris instances. This time, the scheduling logic is in afterPropertiesSet(), which we override when implementing InitializingBean. The method will run as soon as the service starts up.

The interval operator emits a Long every five seconds. Then, the map operator discards that value and replaces it with our message. Finally, we subscribe to the Flux to trigger our logic for each message.

4. Conclusion

In this tutorial, we’ve seen that the utility class SimpMessagingTemplate makes it easy to push server messages through a WebSocket. In addition, we’ve seen two ways of scheduling the execution of a piece of code.

As always, the source code for the examples is available over on GitHub.

Course – LS – All

Get started with Spring and Spring Boot, through the Learn Spring course:

res – REST with Spring (eBook) (everywhere)
Comments are open for 30 days after publishing a post. For any issues past this date, use the Contact form on the site.