【问题标题】:Spring Boot application cannot instantiate a class unless it is annotated with AutowiredSpring Boot 应用程序无法实例化一个类,除非它使用 Autowired 注释
【发布时间】:2019-02-01 04:25:50
【问题描述】:

我有一个 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。

如何让其他策略被实例化?

【问题讨论】:

    标签: java spring-boot


    【解决方案1】:

    因为只有带有 @Autowired 注释的构造函数才会被处理并注入依赖项。 Strategy2Strategy3 的构造函数被忽略,因为上面没有 @Autowired

    你有两个选择:

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

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

    (2) 继续使用构造函数注入。由于所有 Strategy 都是 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;
        }
    }
    

    【讨论】:

    • 感谢您的回复。我收到一个错误,因为我没有看到我必须添加一个默认构造函数。它有效!
    • 是的..正如我之前所说,我没有看到我必须添加默认构造函数。有效!
    • 很高兴听到:P
    猜你喜欢
    • 1970-01-01
    • 2018-05-12
    • 2019-06-07
    • 2020-03-12
    • 2018-11-13
    • 1970-01-01
    • 2017-07-20
    • 2018-08-08
    • 1970-01-01
    相关资源
    最近更新 更多