Tei*_*raz 6 java generics spring dependency-injection
我有界面:
public interface CommandHandler<T extends Command> {
void handle(T command);
}
Run Code Online (Sandbox Code Playgroud)
有一些命令实现Command标记接口
public class CreateCategoryCommand implements Command {
}
public class CreateCategoryCommand implements Command {
}
Run Code Online (Sandbox Code Playgroud)
对于每个命令,我都有适当的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) {
}
}
Run Code Online (Sandbox Code Playgroud)
问题: 我有指挥巴士
@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()>)
}
}
Run Code Online (Sandbox Code Playgroud)
如何从实现具有特定类型的通用接口的应用程序上下文中获取bean?
我解决的方法:
@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;
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2267 次 |
| 最近记录: |