在工厂类中使用依赖注入是不好的做法吗?我应该让我的框架用户负责依赖注入吗?我应该使用方法A还是方法B?
SomeUserClass
package com.impl;
@Service
public class SomeUserClass {
@Autowired
private SMSActionFactoryService actionFactoryService:
@Autowired
private PropertyManager properties;
public void doStuff(){
// approach A
SMSAction action = actionFactoryService.createAction("hello");
// approach B
action = SMSActionFactory.createAction(properties, "hello");
// the user should never call Action::doAction.
// It gets called by the framework on a condition.
scheduler.addAction(State.ERROR, action)
}
}
SMSAction
package com.framework;
public class SMSAction extends Action {
public SMSAction(PropertyManager properties, String message){
}
public void doAction(){
}
}
SMSActionFactoryService
package com.framework;
@Service
public class SMSActionFactoryService {
@Autowired
private PropertyManager properties;
public SMSActionFactory createAction(String message) {
return new SMSActionFactoryService(properties, message);
}
}
SMSActionFactory
package com.framework;
public class SMSActionFactory {
public static SMSActionFactory createAction(PropertyManager properties, String message) {
return new SMSActionFactory(properties, message);
}
}
答案 0 :(得分:0)
我认为你有一个上下文问题,所以答案取决于上下文。但我会给出一些经验,而不是一个正式的(无可辩驳的)答案。基于答案(练习)的标题,我将为您提供我称之为良好做法的提示,这些提示在我开始Spring开发时帮助了我很多。
首先,让我们考虑一下你拥有的依赖注入。你正在连接一个字段,我们知道Spring团队曾经建议我们使用基于构造函数的注入(以及所有强制依赖的断言),你可以看到here。好吧,我知道测试框架的一个问题是无法以简单的方式连接依赖项,但现在它们可以。但使用此模式还有另一个优点,您可以创建bean字段final
。另一个优点是可以防止循环依赖,例如X取决于Y,Y取决于X等等。所以,作为第一个提示,我建议你使用类似的东西:
private final SMSActionFactoryService actionFactoryService:
private final PropertyManager properties;
@Autowired
public SomeUserClass(SMSActionFactoryService actionFactoryService,
PropertyManager properties) {
Assert.notNull(actionFactoryService, "The actionFactoryService bean is null, you should provide the bean to run this application");
Assert.notNull(properties, "The properties bean is null, you should provide the bean to run this application");
this.actionFactoryService = actionFactoryService;
this.properties = properties;
}
这样可以防止任何其他代码部分更改字段值。正如您在Spring autowiring setter/constructor PROs and CONs中所看到的,这是一个偏好主题。
现在,对于第二个提示,我不会将@Service
用于工厂,甚至不会@Component
,因为工厂需要打开以进行扩展并关闭以进行修改 。如果看看here,你会更好地理解。
那位朋友说,我建议你接受B方式。