Reputation: 300
I've got a parent class with a constructor injected dependency:
class ParentClass {
private final MyService service;
@Autowired
ParentClass(MyService service) {
this.service=service;
}
// ...
}
If I inherit from this class, do I always need to redefine a constructor calling the parent constructor?
class ChildClass extends ParentClass {
// Do I really need this?
@Autowired
ChildClass(MyService service) {
super(service);
}
// ...
}
Using setter injection, I seem to be able to keep the dependency in the parent class and do not need to rewire it in the child, which sounds good to me if the child class does not touch the functionality linked to the dependency:
class ParentClass {
private MyService service;
@Autowired
void setMyService(MyService service) {
this.service=service;
}
// ...
}
class ChildClass extends ParentClass {
// ...
}
It seems that if I want to avoid repeating the autowiring code and handling the dependency in the child, I can only do this using setter or field injection.
Is there a cleaner pattern to do this dependency injection or is this a case where field/setter injection has to be used, even though constructor injection is recommended?
Thanks!
Upvotes: 14
Views: 9823
Reputation: 1235
It's not a Spring issue, it's Java. Try removing child class constructor, and see what happens for yourself - your code shouldn't compile. See this answer, it was described before.
Answering your question on dependency injection, yes, @Autowired
works for setter in the parent class, but as long as you don't override it in the subclass (give it a try). The reason is that Spring deals with objects, not classes, so when a subclass is instantiated Spring is not checking annotations on overridden methods in the parent class, unless annotation is marked as @Inherited (@Autowired
is not).
So, you would either have to use @Autowired
for each subclass (which I don't see as a big problem, actually), switch to setter injection, replace subclassing with delegation, or make parent class abstract and use constructor injection only in subclasses.
Upvotes: 7