我正在使用spring自动化一系列策略。首先使用isApplicable()
方法评估每个策略,如果true
,则选择该策略。
我有一个默认策略,其isApplicable()
方法始终返回true
。我希望这个默认策略bean在策略集合中自动装配。
我看到使用@Order
注释执行此操作的一个选项。但问题是这样,我会强制任何实施新策略的人在他们的bean上指定和订购。我想避免这种情况。只希望默认bean在集合中是最后一个。
你知道如何实现这一目标吗?
答案 0 :(得分:1)
从Spring 4开始,@ Order是实现你想要的正确方法。由于您不希望在Strategy接口的任何实现上强制执行@Order,因此这是一种适合您的方法,并确保最后选择默认策略。
作为测试,我创建了StrategyA,StrategyB和DefaultStrategy。如果我将StrategyA或StrategyB标记为适用,则始终首先选择它们。只有两者都不适用时才会选择DefaultStrategy(请参阅最后的输出以查看此测试用例)。
这是一个没有@Order注释的示例策略,它将适用或不适用。我测试了apply = true和false,并得到了预期的结果。
@Component
public class StrategyA implements Strategy {
@Override
public boolean isApplicable() {
return false;
}
@Override
public String getName() {
return "STRATEGY A";
}
}
这是默认策略,始终适用,最后选择。
@Component
@Order(value=Ordered.HIGHEST_PRECEDENCE)
public class DefaultStrategy implements Strategy {
@Override
public boolean isApplicable() {
return true; // Always true
}
@Override
public String getName() {
return "Default; should be chosen last";
}
}
这是确保默认策略最后选择的逻辑。
@Component
public class StrategyChooser {
@Autowired
private List<Strategy> strategies;
public Strategy getStrategy() {
Strategy defaultStrategy = strategies.remove(0); // Remove the default strategy from the top of the list
strategies.add(strategies.size(), defaultStrategy); // And make it last
for (Strategy strategy : getStrategies()) {
System.out.println("Considering strategy="+strategy.getName());
if (strategy.isApplicable())
return strategy;
}
return strategies.get(strategies.size()-1); // Return the last in case the default is not defined
}
}
当所有其他策略“不适用”时输出(证明默认将持续):
Considering strategy=STRATEGY A
Considering strategy=STRATEGY B
Considering strategy=Default; should be chosen last