Какие основные критические замечания к использованию @Autowired в Spring?

«Какие основные критические замечания к использованию @Autowired в Spring?» — вопрос из категории Spring, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Критика @Autowired связана с нарушением принципов чистого кода и тестируемости, особенно при полевом внедрении (@Autowired над полем).

Основные проблемы:

  1. Нарушение принципа инверсии зависимостей (DIP): Класс скрывает свои зависимости, делая их неявными. Невозможно создать экземпляр класса без Spring-контейнера, что усложняет модульное тестирование.
  2. Сложность тестирования: Для создания объекта в тесте требуется инициализировать Spring-контекст или использовать рефлексию для установки мок-зависимостей.
  3. Неизменяемость (Immutability): Полевое внедрение делает поля final невозможными, снижая безопасность в многопоточных сценариях.
  4. Скрытая связность: Трудно отследить все зависимости класса, что усложняет рефакторинг и понимание кода.

Рекомендуемая альтернатива — внедрение через конструктор:

@Service
public class UserService {
    // Зависимость объявлена как final
    private final UserRepository userRepository;

    // Зависимость явно передается и обязательна
    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }
    // ... бизнес-логика
}

Конфигурация в Spring Boot (автоматически): Начиная с Spring 4.3, для класса с одним конструктором аннотация @Autowired не требуется. Spring использует этот конструктор по умолчанию.

Преимущества конструкторного внедрения:

  • Явное объявление зависимостей.
  • Возможность создавать final поля.
  • Простое и чистое модульное тестирование (просто new UserService(mockRepo)).
  • Гарантирует, что объект создается в полностью инициализированном состоянии.