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

时间:2019-04-03 03:50:12

标签: 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;
    }
}

如您所见,我在每个子类中都使用了setter注入。这是一种自动连接其父级的成员变量的好习惯吗?

2 个答案:

答案 0 :(得分:3)

这是Spring团队的DI准则:


以下是Spring推荐的一般指南(请参阅有关基于构造函数的DI或基于Setter的DI的部分):

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

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

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


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

abstract class Payment {
    PaymentService paymentService;


    public Payment(OrderPaymentService paymentService) {
        this.paymentService = paymentService;
    }
}

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

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

    @Autowired
    public CreatePayment(PaymentService paymentService) {
        super(paymentService);
    }
}

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

答案 1 :(得分:0)

我要说的第一件事是,您应该在继承之前使用合成,即使使用Spring(仅在特殊情况下),使用继承也没有意义。

第二件事是“业务视图”,或者用英语怎么说,CancelPayment和CreatePayment在我看来就像是付款服务中的两种方法,我不明白为什么需要单独的对象。