在工厂类中使用依赖注入是不好的做法吗?

时间:2018-01-22 14:44:26

标签: java spring factory-pattern

在工厂类中使用依赖注入是不好的做法吗?我应该让我的框架用户负责依赖注入吗?我应该使用方法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);
    }
}

1 个答案:

答案 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方式