Correctness30 - SpotBugsExtensionForSpringFrameWork/CS5098 GitHub Wiki

Bug pattern name: CONSTRUCTOR_INJECTION_IN_ABSTRACT_CLASS Short Description: We can't use @Autowired on a constructor of an abstract class

Description

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.

public abstract class BallService {

    private RuleRepository ruleRepository;

    @Autowired // Do not add @Autowired annotation on a constructor of an abstract class
    public BallService(RuleRepository ruleRepository) {
        this.ruleRepository = ruleRepository;
    }
}

Solution

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);
    }
}

Theory

"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." "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."

Reference List

https://www.baeldung.com/spring-autowired-abstract-class#constructor-injection