1. Introduction
In this quick tutorial, weβll explain how to use the @Autowired annotation in abstract classes.
Weβll apply @Autowired to an abstract class and focus on the important points we should consider.
2. Setter Injection
We can use @Autowired on a setter method:
public abstract class BallService {
private LogRepository logRepository;
@Autowired
public final void setLogRepository(LogRepository logRepository) {
this.logRepository = logRepository;
}
}
When we use @Autowired on a setter method, we should use the final keyword so that the subclass canβt override the setter method. Otherwise, the annotation wonβt work as we expect.
3. Constructor Injection
We canβt use @Autowired on a constructor of an abstract class.
Spring doesnβt evaluate the @Autowired annotation on a constructor of an abstract class. The subclass should provide the necessary arguments to the super constructor.
Instead, we should use @Autowired on the constructor of the subclass:
public abstract class BallService {
private RuleRepository ruleRepository;
public BallService(RuleRepository ruleRepository) {
this.ruleRepository = ruleRepository;
}
}
@Component
public class BasketballService extends BallService {
@Autowired
public BasketballService(RuleRepository ruleRepository) {
super(ruleRepository);
}
}
4. Cheat Sheet
Letβs wrap up with a few rules to remember.
First, an abstract class isnβt component-scanned since it canβt be instantiated without a concrete subclass.
Second, setter injection is possible in an abstract class, but itβs risky if we donβt use the final keyword for the setter method. The application may not be stable if a subclass overrides the setter method.
Third, as Spring doesnβt support constructor injection in an abstract class, we should generally let the concrete subclasses provide the constructor arguments. This means that we need to rely on constructor injection in concrete subclasses.
And finally, using constructor injection for required dependencies and setter injection for optional dependencies is a good rule of thumb. However, as we can see with some of the nuances with abstract classes, constructor injection is generally more favourable here.
So, we can say that a concrete subclass governs how its abstract parent gets its dependencies. Spring will do the injection as long as Spring wires up the subclass.
5. Conclusion
In this article, we practised using @Autowired within an abstract class and explained a few important key points.
