[英]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. Strategy2
和Strategy3
的构造函数将被忽略,因为上面没有@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.