«1. Введение

В этом кратком руководстве мы объясним, как использовать аннотацию @Autowired в абстрактных классах.

Мы применим @Autowired к абстрактному классу и сосредоточимся на важных моментах, которые следует учитывать.

2. Внедрение сеттера

Мы можем использовать @Autowired в методе установки:

public abstract class BallService {

    private LogRepository logRepository;

    @Autowired
    public final void setLogRepository(LogRepository logRepository) {
        this.logRepository = logRepository;
    }
}

Когда мы используем @Autowired в методе установки, мы должны использовать ключевое слово final, чтобы подкласс не мог переопределить метод установки. В противном случае аннотация не будет работать так, как мы ожидаем.

3. Внедрение конструктора

Мы не можем использовать @Autowired в конструкторе абстрактного класса.

Spring не оценивает аннотацию @Autowired в конструкторе абстрактного класса. Подкласс должен предоставить необходимые аргументы суперконструктору.

Вместо этого мы должны использовать @Autowired в конструкторе подкласса:

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. Шпаргалка

Давайте закончим, вспомнив несколько правил.

Во-первых, абстрактный класс не сканируется по компонентам, поскольку он не может быть создан без конкретного подкласса.

Во-вторых, инъекция сеттера возможна в абстрактном классе, но это рискованно, если мы не используем ключевое слово final для метода сеттера. Приложение может быть нестабильным, если подкласс переопределяет метод установки.

В-третьих, поскольку Spring не поддерживает внедрение конструктора в абстрактный класс, обычно мы должны позволить конкретным подклассам предоставлять аргументы конструктора. Это означает, что нам нужно полагаться на внедрение конструктора в конкретные подклассы.

И, наконец, использование внедрения конструктора для обязательных зависимостей и внедрения сеттера для необязательных зависимостей является хорошим эмпирическим правилом. Однако, как мы можем видеть с некоторыми нюансами абстрактных классов, внедрение конструктора здесь в целом более выгодно.

Итак, на самом деле мы можем сказать, что конкретный подкласс управляет тем, как его абстрактный родитель получает свои зависимости. Spring будет выполнять инъекцию до тех пор, пока Spring подключает подкласс.

5. Заключение

В этой статье мы попрактиковались в использовании @Autowired в абстрактном классе и объяснили несколько важных ключевых моментов.