据我所知,不推荐使用field injection
。应改为使用constructor
。
我在这里尝试做的是在基类的构造函数中使用@Autowired
,并使其可供所有子类访问。在某些子类中,我还需要一些特定的bean来自它们的构造函数@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;
}
}
这会给我一个没有默认构造函数'错误。
它类似于问题similar question and answer,但它在这里不起作用。
我已经潜入了一段时间,我发现这篇文章关于dependency injection
:further read
我认为Setter Injection
是我问题的正确方法吗?
二传手注射:
public abstract class Base {
protected MyDemoService myDemoService;
@Autowired
public void setMyDemoService(MyDemoService myDemoService) {
this.myDemoService = myDemoService;
}
}
我是Java Spring Boot的新手,想要从你们那里获得一些专业知识。任何讨论都将受到高度赞赏!
答案 0 :(得分:3)
不要使用字段注入,使用构造函数注入来调用超级构造函数。
构造函数注入确保在实例化之前正确填充对象,setter注入不会使代码更容易出错(不是另一个nullpointer bug ....)
如果您担心必须编写的额外代码,请使用Project Lombok让Lombok为您生成构造函数代码,如此处所述Why field injection is evil
从Spring 4开始,如果你的类中只有一个构造函数,那么构造函数中不需要@Autowired。
答案 1 :(得分:3)
您提供的代码无法编译。只要在您的基类中没有默认构造函数,就应该在子级中调用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
的多个实施,则必须使用answer that you have mentioned中所述的@Qualifier
。
public Sub(@Qualifier("MySubService") MyDemoService mySubService){
super(mySubService);
}
答案 2 :(得分:2)
我建议使用@Configuration
课程。这样您就可以完全从业务类中删除Spring注释:
public class Sub extends Base {
private final MySubService mySubService;
public Sub(MySubService mySubService, MyDemoService myDemoService){
super(myDemoService);
this.mySubService = mySubService;
}
}
Spring config:
@Configuration
public class SubConfig{
@Bean
public Sub sub(MySubService subService, MyDemoService demoService){
return new Sub(subService, demoService);
}
}
使用Configuration类,您不再依赖于神奇的类路径扫描,而是再次手动实例化bean。这种方法的惊喜要少得多。
答案 3 :(得分:1)
有效!!!!构造函数自动连接的限定符继承注入
基础抽象类DocumentoBase。
sleep(1)
继承的类DocumentoController。
didSet
答案 4 :(得分:-2)
使用构造函数注入不能这样做,你必须使用Base类构造函数的依赖项扩展子类构造函数,并调用正确的super
构造函数(标准Java规则仍然适用,甚至如果你使用Spring)。
Field和Setter注入会正确地执行此操作。
我建议在任何情况下使用Field注入,因为它减少了代码重复。比较:
class A {
@Autowired private Field field;
}
Vs以上。
class A {
private final Field field;
/** plus mandatory javadocs */
@Autowired
public A(Field field) {
this.field = field;
}
}
在构造函数注入示例中,为了让字段按照您想要的方式设置,您需要重复四次...即使我喜欢最终的事情,这种重复只会让代码变得很难。