在抽象基类中使用@autowired

2022-09-03 07:30:13

据我所知,不建议这样做。应该使用代替。field injectionconstructor

我在这里尝试做的是在基类的构造函数中使用,并使其可供所有子类访问。在某些子类中,我还需要一些特定的bean来自它们的构造函数。演示代码如下:@Autowired@Autowired

基类:

public abstract class Base {

    protected final MyDemoService myDemoService;

    @Autowired
    public Base(MyDemoService myDemoService) {
        this.myDemoService = myDemoService;
    }
}

继承(子)类:

public class Sub extends Base {

    private final MySubService mySubService;

    @Autowired
    public Sub(MySubService mySubService) {
        this.mySubService = mySubService;
    }
} 

这将给我一个“没有默认构造函数”错误。
它类似于问题:类似的问题和答案,但它在这里不起作用。


我已经深入研究了一段时间,我发现这篇文章是关于:进一步阅读dependency injection

我认为我的问题是正确的方法吗?Setter Injection

设置器注射:

public abstract class Base {

    protected MyDemoService myDemoService;

    @Autowired
    public void setMyDemoService(MyDemoService myDemoService) {
        this.myDemoService = myDemoService;
    }
}

我是Java Spring Boot的新手,希望从你们那里得到一些专业知识建议。任何讨论将不胜感激!


答案 1

您提供的代码将无法编译。只要在基类中没有默认构造函数,就应该调用 child。super(MyDemoService)

继承(子)类:

public class Sub extends Base {

    private final MySubService mySubService;

    @Autowired
    public Sub(MySubService mySubService, MyDemoService myDemoService){
        super(myDemoService);
        this.mySubService = mySubService;
    }
} 

或者,如果 是MySubServiceMyDemoService

@Autowired
public Sub(MySubService mySubService){
    super(mySubService);
}

只要抽象类中的字段是,就可以在子类中使用它。MyDemoService myDemoServiceprotected

如果您有 多个 实现,则必须按照您提到的答案中所述使用。MyDemoService@Qualifier

public Sub(@Qualifier("MySubService") MyDemoService mySubService){
    super(mySubService);
}

答案 2

不要使用字段注入,而是根据需要使用构造函数注入回调用超级构造函数。

构造函数注入可确保在实例化之前正确填充对象,setter 注入不会,并使代码更容易出错(不是另一个 nullpointer bug....)

如果您担心必须编写的额外代码,请使用龙目岛项目让龙目岛为您生成构造函数代码,如此处所述 为什么字段注入是邪恶的

顺便说一句,从春季4开始,如果你的类中只有一个构造函数,你不需要在构造函数上@Autowired。


推荐