简体   繁体   中英

Class registry in Java with Micronaut

I am trying to do the class registry in java using the below code

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<Class<?>, IRequestHandler<?, ?>> handlerMap;

    public ServiceBus(List<IRequestHandler<?, ?>> 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);
    }
}

controller

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

On

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

The return of getCmdType is not correct and not sure about Function.identity() . Threfore IRequestHandler<C, R> handler = (IRequestHandler<C, R>) handlerMap.get(c.getClass()); is always null

What is the best way to get the command and register with the handler

There are several things about your design that can't work and I am not sure what the real requirements are given what is in the question but the project at github.com/jeffbrown/sanjaisyinterfaces should help.

src/main/java/sanjaisyinterfaces/SomeReturnType.java

package sanjaisyinterfaces;

public class SomeReturnType {
}

src/main/java/sanjaisyinterfaces/SomeOtherReturnType.java

package sanjaisyinterfaces;

public class SomeOtherReturnType {
}

src/main/java/sanjaisyinterfaces/CommandType.java

package sanjaisyinterfaces;

public interface CommandType {
}

src/main/java/sanjaisyinterfaces/SomeCommandType.java

package sanjaisyinterfaces;

public class SomeCommandType implements CommandType {
}

src/main/java/sanjaisyinterfaces/SomeOtherCommandType.java

package sanjaisyinterfaces;

public class SomeOtherCommandType implements CommandType {
}

src/main/java/sanjaisyinterfaces/IRequestHandler.java

package sanjaisyinterfaces;

public interface IRequestHandler<C extends CommandType, R> {
    R handler(C c);
    Class<C> getCmdType();
}

src/main/java/sanjaisyinterfaces/SomeRequestHandler.java

package sanjaisyinterfaces;

import jakarta.inject.Singleton;

@Singleton
public class SomeRequestHandler implements IRequestHandler<SomeCommandType, SomeReturnType> {

    @Override
    public SomeReturnType handler(SomeCommandType someCommandType) {
        System.out.println("SomeRequestHandler is handling a request for SomeCommandType");
        // do whatever needs to be done here
        return null;
    }

    @Override
    public Class getCmdType() {
        return SomeCommandType.class;
    }
}

src/main/java/sanjaisyinterfaces/SomeOtherRequestHandler.java

package sanjaisyinterfaces;

import jakarta.inject.Singleton;

@Singleton
public class SomeOtherRequestHandler implements IRequestHandler<SomeOtherCommandType, SomeOtherReturnType> {

    @Override
    public SomeOtherReturnType handler(SomeOtherCommandType someCommandType) {
        System.out.println("SomeOtherRequestHandler is handling a request for SomeOtherCommandType");
        // do whatever needs to be done here
        return null;
    }

    @Override
    public Class getCmdType() {
        return SomeOtherCommandType.class;
    }
}

src/main/java/sanjaisyinterfaces/IServiceBus.java

package sanjaisyinterfaces;

public interface IServiceBus {
    Object send(CommandType c);
}

src/main/java/sanjaisyinterfaces/ServiceBus.java

package sanjaisyinterfaces;

import jakarta.inject.Singleton;

import java.util.List;
import java.util.Map;
import java.util.function.Function;

import static java.util.stream.Collectors.toMap;

@Singleton
public class ServiceBus implements IServiceBus {

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

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

    @Override
    public Object send(CommandType c) {
        IRequestHandler handler = handlerMap.get(c.getClass());
        if (handler == null)
            throw new UnsupportedOperationException("Unsupported command: " + c.getClass());
        return handler.handler(c);
    }
}

src/main/java/sanjaisyinterfaces/SanjaisyinterfacesCommand.java

package sanjaisyinterfaces;

import io.micronaut.configuration.picocli.PicocliRunner;
import io.micronaut.context.ApplicationContext;

import jakarta.inject.Inject;
import picocli.CommandLine;
import picocli.CommandLine.Command;
import picocli.CommandLine.Option;
import picocli.CommandLine.Parameters;

@Command(name = "sanjaisyinterfaces", description = "...",
        mixinStandardHelpOptions = true)
public class SanjaisyinterfacesCommand implements Runnable {

    @Inject
    ServiceBus serviceBus;

    public static void main(String[] args) throws Exception {
        PicocliRunner.run(SanjaisyinterfacesCommand.class, args);
    }

    public void run() {
        CommandType firstCommand = new SomeCommandType();
        CommandType secondCommand = new SomeOtherCommandType();
        serviceBus.send(firstCommand);
        serviceBus.send(secondCommand);
    }
}

Running that project indicates that the relationships are being recognized as intended:

~ $ mkdir example
~ $ cd example
example $ git clone git@github.com:jeffbrown/sanjaisyinterfaces.git
Cloning into 'sanjaisyinterfaces'...
remote: Enumerating objects: 47, done.
remote: Counting objects: 100% (47/47), done.
remote: Compressing objects: 100% (35/35), done.
remote: Total 47 (delta 8), reused 44 (delta 5), pack-reused 0
Receiving objects: 100% (47/47), 63.88 KiB | 838.00 KiB/s, done.
Resolving deltas: 100% (8/8), done.
example $ 
example $ cd sanjaisyinterfaces 
sanjaisyinterfaces (main)$ ./gradlew run

> Task :run
09:10:39.377 [main] INFO  i.m.context.env.DefaultEnvironment - Established active environments: [cli]
SomeRequestHandler is handling a request for SomeCommandType
SomeOtherRequestHandler is handling a request for SomeOtherCommandType

sanjaisyinterfaces (main)$ 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM