在春季自动对父类字段进行自动连线的最佳方法是什么?

Lau*_*ang 5 java spring

当我使用spring框架时,我发现应该提取的东西,例如,服务组件(或自动装配的成员变量)。代码显示如下:

abstract class Payment {

    PaymentService paymentService;

    void setPaymentService(OrderPaymentService paymentService) {
        this.paymentService = paymentService;
    }

}    

@Component
public class CancelPayment extends Payment{
    private OtherService2 otherSerivce2;

    @Autowired
    @Override
    public void setPaymentService(PaymentService paymentService) {
        super.setPaymentService(paymentService);
    }

    @Autowired
    public CancelPayment(OtherService2 s2) {
        this.otherSerivce2 = s2;
    }
}

@Component
public class CreatePayment extends Payment{
    private OtherService1 otherSerivce1;

    @Autowired
    @Override
    public void setPaymentService(PaymentService paymentService) {
        super.setPaymentService(paymentService);
    }

    @Autowired
    public CreatePayment (OtherService1 s1) {
        this.otherSerivce1 = s1;
    }
}
Run Code Online (Sandbox Code Playgroud)

如您所见,我在每个子类中都使用了setter注入。这是比自动装配其父母的成员变量更好的做法吗?

Iva*_*anM 5

这是Spring团队的DI准则:


Spring推荐的一般准则如下(请参阅有关基于构造函数的DI或基于Setter的DI的部分):

  • 对于强制性依赖性或针对不变性,请使用构造函数注入

  • 对于可选或可变的依赖项,请使用setter注入

  • 大多数情况下避免现场注入


现在,如果您确定要使用PaymentService,我建议您像这样在抽象类中使用构造函数注入,这样对象就不会在没有依赖关系的情况下实例化,还使其更不可变,更清晰和线程安全:

abstract class Payment {
    PaymentService paymentService;


    public Payment(OrderPaymentService paymentService) {
        this.paymentService = paymentService;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,您可以像这样在扩展类上直接调用super:

@Component
public class CreatePayment extends Payment{
    private OtherService1 otherSerivce1;

    @Autowired
    public CreatePayment(PaymentService paymentService) {
        super(paymentService);
    }
}
Run Code Online (Sandbox Code Playgroud)

这仅允许您使用构造函数注入父类(如果paymentService是必需的)。

  • 是的,实际上构造函数 DI 是最受欢迎的一个,由于继承,这是一个更复杂的例子,但是是的。不推荐使用 Field DI,因为它容易产生代码异味,并且您不能使其不可变(final),从而降低线程安全性。使用 setter,您可能会冒着不被调用的风险,因此可能不会提供实例依赖项(除非您使用 @Required 对其进行注释)。所以是的,我强烈建议尽可能使用构造函数注入。 (2认同)
  • @Steve总是使用构造函数自动装配。它更容易测试,您可以在ctor中编写验证逻辑,而不是编写`PostConstruct`方法,并且-我认为最大的好处-它提供了有关bean依赖关系的非常清晰的文档。 (2认同)