Какие аннотации используются для внедрения зависимостей в Spring и где их можно применять?

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

Ответ

В Spring для внедрения зависимостей (Dependency Injection, DI) используются несколько аннотаций, которые можно применять в разных местах класса.

Основные аннотации:

  • @Autowired (Spring-specific)
  • @Inject (стандартная JSR-330)
  • @Resource (стандартная JSR-250)

Точки внедрения (с примером @Autowired):

  1. Внедрение через конструктор (Constructor Injection) - рекомендуется. Зависимости объявляются как final, что гарантирует их инициализацию и неизменяемость.

    @Service
    public class OrderService {
        private final OrderRepository repository;
        private final PaymentService paymentService;
    
        @Autowired // Необязательно в Spring 4.3+, если конструктор один
        public OrderService(OrderRepository repository, PaymentService paymentService) {
            this.repository = repository;
            this.paymentService = paymentService;
        }
    }
  2. Внедрение в поле (Field Injection). Краткий, но менее тестируемый способ (требует Spring-контейнера или рефлексии для тестов).

    @RestController
    public class UserController {
        @Autowired
        private UserService userService;
    }
  3. Внедрение через сеттер (Setter Injection). Подходит для опциональных или изменяемых зависимостей.

    @Component
    public class DataProcessor {
        private Validator validator;
    
        @Autowired
        public void setValidator(Validator validator) {
            this.validator = validator;
        }
    }

Дополнительно: Аннотация @Value используется для внедрения значений из properties-файлов или SpEL-выражений.

@Value("${app.page.size:10}")
private int pageSize;