提问者:小点点

在抽象基类中使用@autow的


据我所知,不建议使用字段注入。应该使用构造函数来代替。

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

基类:

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;
    }
} 

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

我已经深入研究了一段时间,我发现了这篇关于依赖注入的文章:进一步阅读

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

塞特注射:

public abstract class Base {

    protected MyDemoService myDemoService;

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

我是Java新来的,想从你们那里得到一些专业建议。任何讨论都将不胜感激!


共3个答案

匿名用户

你提供的代码不会编译。只要在你的基类中没有默认构造函数,你就应该在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);
}

匿名用户

不要使用字段注入,酌情使用构造函数注入回调超级构造函数。

构造函数注入确保您的对象在实例化之前被正确填充,setter注入不会,并且使代码更容易bug(不是另一个空指针bug……)

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

顺便说一句,从Spring 4开始,如果您的类中只有一个构造函数,则在构造函数上不需要@Autow了。

匿名用户

我建议使用@Configuration类。这样您就可以从业务类中完全删除Spring注释:

public class Sub extends Base {

    private final MySubService mySubService;

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

Spring配置:

@Configuration
public class SubConfig{

    @Bean
    public Sub sub(MySubService subService, MyDemoService demoService){
        return new Sub(subService, demoService);
    }
}

使用Configuration类,您不再依赖神奇的类路径扫描,而是再次手动实例化bean。这种方法的惊喜要少得多。