简体   繁体   English

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

[英]Spring Boot application cannot instantiate a class unless it is annotated with Autowired

I have a Spring Boot application that has a factory class with determines which strategy to instantiate based on a string. 我有一个具有工厂类的Spring Boot应用程序,该类可根据字符串确定要实例化的策略。 The strategy factory class has 3 constructors. 策略工厂类具有3个构造函数。 One for each of the strategies. 每个策略一个。 Here is a generalized version of the class: 这是该类的通用版本:

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");
        }
    }
}

When trying to instantiate one of the strategies, only the one that is @Autowired will be instantiated. 尝试实例化其中一种策略时,只会实例化@Autowired策略。 If I try to instantiate the others, it returns null. 如果我尝试实例化其他对象,则返回null。

How can I get the other strategies to be instantiated? 我如何才能实例化其他策略?

Because only the constructors that are annotated with @Autowired will get processed and inject the dependencies . 因为只有用@Autowired注释的构造函数才会被处理并注入依赖项。 The constructor for Strategy2 and Strategy3 are ignored since there are no @Autowired on it. Strategy2Strategy3的构造函数将被忽略,因为上面没有@Autowired

You have two options : 您有两种选择:

(1) Change to use field injection rather than constructor injections: (1)更改为使用字段注入而不是构造函数注入:

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

    StrategyFactory(){}
}

(2) Keep to use constructor injection. (2)继续使用构造函数注入。 As all Strategy is GenericStrategy , so you can auto-wire a list of GenericStrategy in constructor instead. 由于所有策略都是GenericStrategy ,因此您可以在构造函数中自动GenericStrategy列表。 Then check its class to return the actual instance. 然后检查其类以返回实际实例。

The codes will look likes the followings: 这些代码如下所示:

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;
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM