Приложение Spring Boot не может создать экземпляр класса, если он не помечен Autowired - PullRequest
0 голосов
/ 31 января 2019

У меня есть приложение 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 голосов
/ 31 января 2019

Потому что только конструкторы, помеченные @Autowired, будут обрабатываться и внедрять зависимости.Конструктор для Strategy2 и Strategy3 игнорируется, поскольку на нем нет @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;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...