Spring Boot应用程序无法实例化一个类,除非使用Autowired对其进行了注释

时间:2019-01-31 19:55:59

标签: java spring-boot

我有一个Spring Boot应用程序,该应用程序具有一个工厂类,该类可以根据字符串确定要实例化的策略。 策略工厂类具有3个构造函数。每个策略一个。 下面是类的一般化版本:

public class StrategyFactory {
    private Strategy1 strategy1;
    private Strategy2 strategy2;
    private Strategy3 strategy3;

    @Autowired
    public StrategyFactory(Strategy1 strategy1) {
        this.strategy1 = strategy1;
    }

    public StrategyFactory(Strategy2 strategy2) {
        this.strategy2 = strategy2;
    }

    public StrategyFactory(Strategy3 strategy3) {
        this.strategy3 = strategy3;
    }

    public GenericStrategy getTrailerStrategy(String strategy) {
        LOGGER.info("Retrieving Strategy Class for {}", strategy);
        if (strategy.equals("CLOSE_DETAIL")) {
            return strategy1;
        } 
        else if(strategy.equals("LOAD_TRAILER")) {
            return strategy2;
        } 
        else if(strategy.equals("CLOSE_SUMMARY")) {
            return strategy3;
        } 
        else {
            throw new InvalidStrategyTypeException("Invalid Strategy Type");
        }
    }
}

当尝试实例化其中一种策略时,只会实例化@Autowired的策略。如果我尝试实例化其他实例,它将返回null。

我如何才能实例化其他策略?

1 个答案:

答案 0 :(得分:2)

由于仅被注释与构造@Autowired将得到处理和注入的依赖关系。为构造Strategy2Strategy3将被忽略,因为没有@Autowired就可以了。

您有两种选择:

(1)更改为使用字段注入而不是构造函数注入:

public class StrategyFactory {
    @Autowired
    private Strategy1 strategy1;
    @Autowired
    private Strategy2 strategy2;
    @Autowired
    private Strategy3 strategy3;

    StrategyFactory(){}
}

(2)保持到使用构造器注入。由于所有策略都是GenericStrategy,因此您可以在构造函数中自动关联GenericStrategy的列表。然后检查其类以返回实际实例。

在代码看起来喜欢如下:

public class StrategyFactory {
    private List<GenericStrategy> strategy; 

    @Autowired
    public StrategyFactory(List<GenericStrategy> strategy) {
        this.strategy = strategy1;
    }

    public GenericStrategy getTrailerStrategy(String strategy) {
        LOGGER.info("Retrieving Strategy Class for {}", strategy);
        GenericStrategy result = null; 
        if (strategy.equals("CLOSE_DETAIL")) {
            result = getStrategy(Strategy1.class);
        } 
        else if(strategy.equals("LOAD_TRAILER")) {
            result = getStrategy(Strategy2.class);
        } 
        else if(strategy.equals("CLOSE_SUMMARY")) {
           result = getStrategy(Strategy3.class);
        } 
        else {
            throw new InvalidStrategyTypeException("Invalid Strategy Type");
        }

        if(result == null){
          throw new RuntimeException("Fail to load the strategy....");
        }
    }

    private <T> GenericStrategy getStrategy(Class<T> clazz){
        for(GenericStrategy s : strategy){
          if(clazz.isInstance(s)){
            return s;
          }
        }
        return null;
    }
}