spring autowire collection,命令default bean last

时间:2016-02-03 18:17:01

标签: java spring

我正在使用spring自动化一系列策略。首先使用isApplicable()方法评估每个策略,如果true,则选择该策略。 我有一个默认策略,其isApplicable()方法始终返回true。我希望这个默认策略bean在策略集合中自动装配。

我看到使用@Order注释执行此操作的一个选项。但问题是这样,我会强制任何实施新策略的人在他们的bean上指定和订购。我想避免这种情况。只希望默认bean在集合中是最后一个。

你知道如何实现这一目标吗?

1 个答案:

答案 0 :(得分:1)

从Spring 4开始,@ Order是实现你想要的正确方法。由于您不希望在Strategy接口的任何实现上强制执行@Order,因此这是一种适合您的方法,并确保最后选择默认策略。

  1. 反直觉地,使用@Order注释默认策略(value = Ordered.HIGHEST_PRECEDENCE)
  2. 不要使用@Order注释任何其他实现。
  3. 在从集合中选择策略之前,从列表中删除最高策略(保证是默认策略)并将其放在集合的底部。下面的代码演示了这一点。
  4. 迭代策略并选择第一个适用的策略。
  5. 作为测试,我创建了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