春季:如何从实现通用接口的应用程序上下文中获取bean? [英] Spring: how to get bean from application context which implements generic interface?
本文介绍了春季:如何从实现通用接口的应用程序上下文中获取bean?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我有界面:
public interface CommandHandler<T extends Command> {
void handle(T command);
}
有些命令实现了 Command 标记界面
There are commands which implement Command marker interface
public class CreateCategoryCommand implements Command {
}
public class CreateCategoryCommand implements Command {
}
对于每个命令,我都有适当的 CommandHandler 实现:
For each command I have apropriate CommandHandler implementations:
@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?
How to get bean from application context which implements generic interface with particular type?
推荐答案
我解决的方式:
@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;
}
}
这篇关于春季:如何从实现通用接口的应用程序上下文中获取bean?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文