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!
Use Constructor Injection when Object must be created with all of its dependency. P. S. - If you want to learn how to develop RESTful Web Service using Spring MVC in-depth, I suggest you join the REST with Spring certification class by Eugen Paraschiv. One of the best courses to learn REST with Spring MVC.
If there is only one property in a spring bean class then use constructor injection as constructor executes before methods constructor injection will be faster than setter injection.
Constructor injection makes code more robust. It allows us to create immutable objects, preventing NullPointerException s and other errors. You can find the code example on GitHub.
Overriding: Setter injection overrides the constructor injection. If we use both constructor and setter injection, IOC container will use the setter injection. Changes: We can easily change the value by setter injection. It doesn't create a new bean instance always like constructor.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With