在抽象基类中使用@autowired

Vig*_*gor 14 java spring javabeans spring-boot

据我所知,field injection不推荐.应该使用constructor.

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

基类:

public abstract class Base {

    protected final MyDemoService myDemoService;

    @Autowired
    public Base(MyDemoService myDemoService) {
        this.myDemoService = myDemoService;
    }
}
Run Code Online (Sandbox Code Playgroud)

继承(子)类:

public class Sub extends Base {

    private final MySubService mySubService;

    @Autowired
    public Sub(MySubService mySubService) {
        this.mySubService = mySubService;
    }
} 
Run Code Online (Sandbox Code Playgroud)

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


我已经潜入了一段时间,我发现这篇文章dependency injection:进一步阅读

我在想Setter Injection我的问题是正确的方法吗?

塞特犬注射:

public abstract class Base {

    protected MyDemoService myDemoService;

    @Autowired
    public void setMyDemoService(MyDemoService myDemoService) {
        this.myDemoService = myDemoService;
    }
}
Run Code Online (Sandbox Code Playgroud)

我是Java Spring Boot的新手,想要从你们那里获得一些专业知识.任何讨论都将受到高度赞赏!

Ser*_*hyr 6

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

继承的(子)类:

public class Sub extends Base {

    private final MySubService mySubService;

    @Autowired
    public Sub(MySubService mySubService, MyDemoService myDemoService){
        super(myDemoService);
        this.mySubService = mySubService;
    }
} 
Run Code Online (Sandbox Code Playgroud)

或者,如果MySubServiceMyDemoService

@Autowired
public Sub(MySubService mySubService){
    super(mySubService);
}
Run Code Online (Sandbox Code Playgroud)

只要您MyDemoService myDemoService在抽象类中的字段protected都可以在子类中使用它。

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

public Sub(@Qualifier("MySubService") MyDemoService mySubService){
    super(mySubService);
}
Run Code Online (Sandbox Code Playgroud)


joh*_*384 -2

您不能通过构造函数注入来做到这一点,您必须使用基类构造函数的依赖项来扩展子类构造函数,并调用正确的super构造函数(即使您使用 Spring,标准 Java 规则仍然适用)。

然而,Field 和 Setter 注入可以正确地做到这一点。

在任何情况下我都会推荐字段注入,因为它减少了代码重复。比较:

class A {
    @Autowired private Field field;
}
Run Code Online (Sandbox Code Playgroud)

对比。

class A {
    private final Field field;

    /** plus mandatory javadocs */
    @Autowired
    public A(Field field) {
        this.field = field;
    }
}
Run Code Online (Sandbox Code Playgroud)

在构造函数注入示例中,您重复四次只是为了按照您想要的方式设置字段...尽管我喜欢将事情完成,但这种重复只会使更改代码变得困难。