Reputation: 618
I started to use constructor injection in my projects since Spring declared field injection to be deprecated. Actually, the code feels prettier and more strict, I'm ok with that. But I encountered a pattern which seems a bit...weird and verbose to me:
I have an abstract service bean class (with @Service
annotation), which has, say 2 dependencies, injected directly in the constructor:
@Autowired
public AbstractService(DependencyA depA, DependencyB depB) {
this.depA = depA;
this.depB = depB;
}
Then I have multiple services bean classes (still with @Service
annotation) extending the abstract one.
And I don't know if there is another way but this is where I find a bit verbose and repetitive having to inject the dependencies for the parent, in each sub-class constructor:
@Service
public class ServiceA extends AbstractService {
private final DepC depC;
@Autowired
public ServiceA(DepA depA, DepB depB, DepC depC) {
super(depA, depB);
this.depC = depC;
}
}
I just wanted to know if this is the right way, and what you think about this ?
Upvotes: 5
Views: 8599
Reputation: 17085
The @Autowired
on AbstractService
doesn't do anything. Change it to:
@Service
public class ServiceA extends AbstractService {
private final DepC depC;
@Autowired
public ServiceA(DepA depA, DepB depB, DepC depC) {
super(depA, depB);
this.depC = depC;
}
}
...
public AbstractService(DependencyA depA, DependencyB depB) {
this.depA = depA;
this.depB = depB;
}
I'm ok with this setup.
For me, the main benefits of using constructor injection is to inform the developer what are the external dependencies. I find it useful when writing unit test. When writing mocks, you just know what needs to be mocked.
An other benefit is to highlight when a Class has too many dependencies, it gives a hint that refactoring may be in order.
The alternative would be using setter injection (while keeping the informational aspect), but I've grown to enjoy constructor injection.
Upvotes: 4
Reputation: 140633
My answer is focusing about the "verbose and repetitive" part in your question; I let others decide how "correct" your usage of annotations is.
Even with Spring and its DI framework, in the end we are still talking about Java source code!
And in Java, if your base class only offers a constructor that takes some A and B; then of course your subclass has to make a call super(A a, B b); and of course, those values a and b have to come from somewhere!
So, what you call "verbose and repetitive" is a direct consequence of using Java.
In other words: there is no way to avoid that part!
Upvotes: 2