据我所知,不建议使用字段注入
。应该使用构造函数
来代替。
我在这里尝试做的是在基类的构造函数中使用@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新来的,想从你们那里得到一些专业建议。任何讨论都将不胜感激!
你提供的代码不会编译。只要在你的基类中没有默认构造函数,你就应该在child中调用super(MyDemoService)
。
继承(子)类:
public class Sub extends Base {
private final MySubService mySubService;
@Autowired
public Sub(MySubService mySubService, MyDemoService myDemoService){
super(myDemoService);
this.mySubService = mySubService;
}
}
或者,如果MySubService
是MyDemoService
的实现
@Autowired
public Sub(MySubService mySubService){
super(mySubService);
}
只要您在抽象类中的字段MyDemoService myDemoService
是protected
,您就可以在子类中使用它。
如果您有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。这种方法的惊喜要少得多。