我有界面:
public interface CommandHandler<T extends Command> {
void handle(T command);
}
有一些命令可以实现命令标记接口
public class CreateCategoryCommand implements Command {
}
public class CreateCategoryCommand implements Command {
}
对于每个命令,我都有适当的 CommandHandler 实现:
@Component
public class CreateProductCommandHandler implements CommandHandler<CreateProductCommand> {
@Override
public void handle(CreateProductCommand command) {
System.out.println("Command handled");
}
}
@Component
public class CreateCategoryCommandHandler implements CommandHandler<CreateCategoryCommand> {
@Override
public void handle(CreateCategoryCommand command) {
}
}
问题: 我有命令总线
@Component
public class SimpleCommandBus implements CommandBus {
@Autowired
private ApplicationContext context;
@Override
public void send(Command command) {
// OF COURSE, THIS NOT COMPILED, BUT I NEED SOMETHING LIKE THIS
CommandHandler commandHandler = context.getBean(CommandHandler<command.getClass()>)
}
}
如何从实现具有特定类型的通用接口的应用程序上下文中获取bean?
答案 0 :(得分:0)
我解决了它的方式:
@Component
public class SimpleCommandBus {
private final Logger logger;
private final Set<CommandHandler<?>> handlers;
private final Map<Class<?>, CommandHandler<?>> commandHandlersCache = new WeakHashMap<>();
public SimpleCommandBus(Logger logger, Set<CommandHandler<?>> handlers) {
this.logger = logger;
this.handlers = handlers;
}
public void send(Command command) {
CommandHandler<Command> commandHandler = getCommandHandler(command);
if (commandHandler != null)
commandHandler.handle(command);
else
logger.error("Can't handle command " + command);
}
@SuppressWarnings("unchecked")
private <C extends Command> CommandHandler<C> getCommandHandler(C command) {
Class<?> commandType = command.getClass();
if (commandHandlersCache.containsKey(commandType))
return (CommandHandler<C>) commandHandlersCache.get(commandType);
for (CommandHandler<?> haandler : handlers) {
Class<?> supportedCommandType = resolveTypeArgument(haandler.getClass(), CommandHandler.class);
if (commandType.isAssignableFrom(supportedCommandType)) {
commandHandlersCache.put(commandType, haandler);
return (CommandHandler<C>) haandler;
}
}
commandHandlersCache.put(commandType, null);
return null;
}
}