Что делает аннотация @Autowired в Spring?

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

Ответ

@Autowired — это аннотация Spring Framework для автоматического внедрения зависимостей (Dependency Injection, DI). Она указывает контейнеру Spring, где и какой бин необходимо инжектировать.

Как работает:

  1. Spring сканирует компоненты (классы, помеченные @Component, @Service, @Repository, @Controller).
  2. Создаёт и управляет их экземплярами (бинами) в ApplicationContext.
  3. При обнаружении поля, конструктора или сеттера с @Autowired, Spring находит подходящий бин по типу и автоматически присваивает его (инжектирует).

Основные способы использования:

  • Внедрение через поле (Field Injection):

    @Service
    public class OrderService {
        @Autowired
        private PaymentService paymentService; // Spring инжектирует бин PaymentService
    }
  • Внедрение через конструктор (Constructor Injection — рекомендуется):

    @Service
    public class OrderService {
        private final PaymentService paymentService;
    
        @Autowired // Начиная с Spring 4.3, для единственного конструктора аннотацию можно опустить
        public OrderService(PaymentService paymentService) {
            this.paymentService = paymentService;
        }
    }
  • Внедрение через сеттер (Setter Injection):

    @Service
    public class OrderService {
        private PaymentService paymentService;
    
        @Autowired
        public void setPaymentService(PaymentService paymentService) {
            this.paymentService = paymentService;
        }
    }

Ключевые моменты:

  • @Autowired(required = false) делает зависимость опциональной. Если подходящий бин не найден, поле останется null.
  • Для разрешения неоднозначности, когда существует несколько бинов одного типа, используются аннотации @Qualifier("beanName") или @Primary.
  • Внедрение через конструктор является предпочтительным, так как оно делает зависимости явными, упрощает тестирование и гарантирует, что объект создаётся в полностью инициализированном состоянии.