java - 策略模式@Service 重复组件名的两种用法
问题描述
在 Spring Boot 的帮助下实现了一个非常简单的策略模式:
我有一个界面:
public interface IOneStrategy {
void executeTheThing();
}
我有一个这样的策略 One 的实现:
@Service("FIRST")
public class OneStrategyFirst implements IOneStrategy {
@Override
public void executeTheThing() {
System.out.println("OneStrategyFirst.executeTheThing");
}
}
我有一个使用注入实现的类:
@Service
public class ExecuteStrategyOne {
private Map<String, IOneStrategy> strategies;
public void executeStrategyOne(String name) {
if (!strategies.containsKey(name)) {
throw new IllegalArgumentException("The key " + name + " does not exist.");
}
strategies.get(name).executeTheThing();
}
}
并且这些实现将由 Spring boot 通过使用 name FIRST
、 'SECOND' 等自动注入(假设这只是一个 String 等。效果很好。)。
但现在我想通过第二个接口实现另一种策略:
public interface ITwoStrategy {
void executeTheThing();
}
以及策略的执行服务:
@Service
public class ExecuteStrategyTwo {
private Map<String, ITwoStrategy> strategies;
...
}
现在是有问题的部分,因为我的应用程序使用相同的名称,应该将其作为上述地图的键的一部分,我想使用以下内容:
@Service("FIRST")
public class TwoStrategyFirst implements ITwoStrategy {
@Override
public void executeTheThing() {
System.out.println("TwoStrategyFirst.executeTheThing");
}
}
这当然会导致基于重复的 bean 名称的异常。确实需要名称FIRST
来区分实现。
我已经找到了@Qualifier
可以用来代替的东西@Service(FIRST)
@Service
@Qualifier(FIRST)
public class TwoStrategyFirst implements ITwoStrategy {
@Override
public void executeTheThing() {
System.out.println("TwoStrategyFirst.executeTheThing");
}
}
不幸的是,它并没有通过使用限定符的名称将类注入到映射中,这不是我打算做的。
是否存在与在策略执行中获取地图键相同的解决方案@Service("FIRST")
?
解决方案
我可以通过使用 Qualifier 注释来使用解决方案,如下所示:
@Service
@Qualifier(FIRST)
public class TwoStrategyFirst implements ITwoStrategy {
...
}
基于此,通过一些代码或多或少有一个简单的解决方案:
@Service
public class ExecuteStrategyTwo {
private Map<String, ITwoStrategy> strategies;
public ExecuteStrategyOne(List<ITwoStrategy> strategies) {
this.strategies = strategies.stream()
.collect(
Collectors.toMap(k -> k.getClass().getDeclaredAnnotation(Qualifier.class).value(), Function.identity()));
}
这会将所有实现注入到构造函数列表中,并将通过使用限定符注释转换为映射。
推荐阅读
- javascript - prevState 在 Enzyme 测试中未定义,但在组件中定义
- angular - 如何使用此自定义管道
- arrays - 从 postgresql 函数返回 BIGINT[]
- r - 没有安装Stata的R中的Stata公式
- php - 由于 PHP 错误,WordPress 网站无法启动
- python - 找不到带有 BeautifulSoup 的容器
- .net - 运行 Visual Studio 安装程序来安装额外功能是否会删除以前安装的功能?
- c++ - OpenMP 中树结构的线程安全
- vue.js - 将插槽嵌套在 vue 的插槽中
- c# - 如何从数组中删除一个元素并将其余元素移回?(C#)