Spring Boot (3) Selecting the service dynamically

 1. Defining the services implementing an interface

The aim is to get a service dynamically by its class name.

First, a simple interface is defined (IProcess.java)

package websocket.services;

import java.util.Map;

import org.springframework.messaging.simp.SimpMessageSendingOperations;

public interface IProcess {
    public boolean execute(SimpMessageSendingOperations messagingTemplate, String subscription, Map<String, Object> map);
}

Let's create some services implementing this interface (but only one is shown) for instance Process01

package websocket.services;

import java.util.Map;

import org.springframework.messaging.simp.SimpMessageSendingOperations;
import org.springframework.stereotype.Service;

@Service("Proces01")
public class Process01 implements IProcess{

    @Override
    public boolean execute(SimpMessageSendingOperations messagingTemplate, String subscription, Map<String, Object> map) {
        for (int i=0; i<10; i++) {
            messagingTemplate.convertAndSend(
                    subscription, 
                    i+ map.get("text").toString() + 
                    "  Hello...++....., " + 
                    map.get("name").toString() + " " + 
                    map.get("idSession").toString());
        }    
        return true;
    }
}


2. A service that selects the service by its class name

Let's create the service that selects the service to execute by its class name

package websocket.services;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.simp.SimpMessageSendingOperations;
import org.springframework.stereotype.Service;

@Service
public class ProcessServiceSelectorByName {
    private final Map<String, IProcess> mpProcessByName;

    @Autowired
    public ProcessServiceSelectorByName(List<IProcess> processServices) {
        //Convert list to map whose key is the class name
        mpProcessByName = processServices.stream()
                .collect(Collectors.toMap(e-> e.getClass().getSimpleName(), e->e));
    }

    // First, get the desired bean by its name from the map and then execute its "execute" method
    public boolean execute(SimpMessageSendingOperations messagingTemplate, String subscription,    Map<String, Object> map) {
        //get class name in the map
        String clsName=map.get("klassName").toString();
        //Get the service by its name
        IProcess process = mpProcessByName.get(clsName);
        //Execute its "execute method"
        return process.execute(messagingTemplate, subscription, map);
    }
}

The important thing to notice (see Baeldung) is that Spring Boot offers a bean that is a list of services that implements that interface that can be got by the @Autowired annotation List<IProcess> 

Converting it to a map, we can get the desired service and execute its method "execute"





 








Comentarios

Entradas populares de este blog

Spring Boot (5) Bootstrap 5 multilevel dropdown menu

Spring Boot (2) Websockets. Subscriptions of only one member

SpringBoot (10) Authentication (1). Server certificate, application.yml and Application.java