es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Registro de clases en Java con Micronaut

Estoy tratando de hacer el registro de clase en Java utilizando el siguiente código:

public interface IServiceBus {
    <c, r=""> R send(C c);
}

public interface IRequestHandler<c, r=""> {
    R handler(C c);
    default Class<c> getCmdType(){
        return (Class<c>) this.getClass();
    };
}

@Singleton
public class ServiceBus implements IServiceBus {

    private final Map<><?>, IRequestHandler<?, ?>> handlerMap;

    public ServiceBus(List<><?, ?>> handlers) {
        handlerMap = handlers.stream()
                .collect(toMap(
                        IRequestHandler::getCmdType,
                        Function.identity()
                ));
    }

    @Override
    public <c, r=""> R send(C c) {
        IRequestHandler<c, r=""> handler = (IRequestHandler<c, r="">) handlerMap.get(c.getClass());
        if (handler == null)
            throw new UnsupportedOperationException("Unsupported command: " + c.getClass());
        return handler.handler(c);
    }
}

Controlador:

public Mono<><?>> getById(@NotBlank String id) {
    var item = _iserviceBus.<createproductcommand, createproductcommand="">send(new CreateProductCommand());
    return null;
}

En:

handlerMap = handlers.stream()
                .collect(toMap(
                        IRequestHandler::getCmdType,
                        Function.identity()
                ));

El valor devuelto por getCmdType no es correcto y no estoy seguro acerca de Function.identity(). Por lo tanto, IRequestHandler<c, r=""> handler = (IRequestHandler<c, r="">) handlerMap.get(c.getClass()); siempre es nulo.

¿Cuál es la mejor manera de obtener el comando y registrarlo con el controlador?</c,></c,></createproductcommand,></c,></c,></c,></c,></c,>

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Para registrar correctamente el controlador con su comando asociado, debes hacer los siguientes cambios:

    1. Modifica el método getCmdType() en la interfaz IRequestHandler para que devuelva el tipo de clase específica del comando que maneja:
    default Class<c> getCmdType(){
        ParameterizedType parameterizedType = (ParameterizedType) getClass().getGenericInterfaces()[0];
        return (Class<c>) parameterizedType.getActualTypeArguments()[0];
    }
    

    Esto devuelve el tipo de clase específico del comando utilizado por el controlador.

    1. En lugar de usar Function.identity(), simplemente puedes usar el objeto handler en sí como valor del Map:
    handlerMap = handlers.stream()
            .collect(Collectors.toMap(
                    IRequestHandler::getCmdType,
                    handler -> handler
            ));
    

    De esta manera, el objeto de controlador específico se asocia con su clase de comando correspondiente.

    Con estos cambios, ahora puedes recuperar correctamente el objeto de controlador para una clase de comando dada:

    IRequestHandler<c, r=""> handler = (IRequestHandler<c, r="">) handlerMap.get(c.getClass());
    if (handler == null) {
        throw new UnsupportedOperationException("Comando no compatible: " + c.getClass());
    }
    return handler.handler(c);
    

    Esto recupera el objeto de controlador específico asociado con la clase de comando dada e invoca su método handler() para procesar el comando.</c,></c,>

Comments are closed.