Разница между @Inject и @Autowired в Spring Framework: когда и что использовать?
Я изучаю несколько блогов по SpringSource, и в одном из них автор использует аннотацию @Inject
. Я полагаю, что он также мог бы воспользоваться @Autowired
.
Вот фрагмент кода:
@Inject private CustomerOrderService customerOrderService;
В чем же разница между использованием @Inject
и @Autowired
? Буду признателен, если кто-то объяснит их различия и в каких ситуациях следует использовать каждую из аннотаций.
5 ответ(ов)
Для обработки ситуации, когда нет необходимой проводки, в Spring можно использовать аннотацию @Autowired
с атрибутом required
, установленным в false
. Это позволяет избежать исключения, если соответствующий бин не найден.
Однако при использовании @Inject
нужно учитывать, что интерфейс Provider
работает с компонентами, что означает, что бин не инжектируется напрямую, а получается через Provider
. Это позволяет динамически получать экземпляр бина только при необходимости, что может быть полезно в некоторых сценариях.
Лучше использовать @Inject всегда. Это подход конфигурации на основе Java (предоставленный Sun), который делает ваше приложение независимым от фреймворка. Таким образом, если вы решите использовать Spring, ваши классы по-прежнему будут работать.
Используя @Autowired, вы ограничиваете себя только Spring, так как @Autowired — это аннотация, предоставленная конкретно этим фреймворком.
В дополнение к вышеизложенному:
- По умолчанию область видимости для бинов с аннотацией
@Autowired
в Spring — Singleton, тогда как при использовании аннотации@Inject
из JSR 330 область видимости работает как прототип в Spring. - В JSR 330 отсутствует эквивалент аннотации
@Lazy
для@Inject
. - Также в JSR 330 нет эквивалента аннотации
@Value
для@Inject
.
В вашем вопросе вы упомянули, что у аннотации @Inject
отсутствует атрибут required
. Давайте разберемся.
Аннотация @Inject
, которая используется в таких фреймворках, как CDI (Contexts and Dependency Injection) в Java, не предоставляет атрибута required
, как это делает, например, аннотация @Autowired
в Spring. Это связано с тем, что @Inject
следует спецификации JSR-330 и выполняет инъекцию зависимостей без дополнительных настроек по умолчанию.
Если вам нужно указать, что зависимость должна быть обязательной, вы можете воспользоваться следующим методом:
- Убедитесь, что класс, который вы инжектируете, является
@Singleton
или@RequestScoped
, что обеспечивает его создание единственного экземпляра. - Если зависимость не может быть разрешена, то контейнер CDI выбросит исключение
UnsatisfiedDependencyException
, указывающее на то, что требуемая зависимость отсутствует.
Если вам нужно более специфичное поведение, например, указывать, что инъекция должна быть обязательной, вы можете использовать конструкцию проверки в вашем коде. Например:
@Inject
private MyService myService;
@PostConstruct
public void init() {
if (myService == null) {
throw new IllegalStateException("MyService is required and must not be null");
}
}
Таким образом, вы явным образом проверяете наличие зависимости после инъекции и можете управлять поведением в случае, если она отсутствует.
Надеюсь, это поможет прояснить ситуацию! Если у вас есть дополнительные вопросы, не стесняйтесь спрашивать.
@Autowired(required=false)
По умолчанию при использовании @Autowired требуется выполнение инъекции зависимостей, так как значение атрибута required истинно по умолчанию. Мы можем изменить это поведение, добавив @Autowired(required=false). В этом случае, если bean не найден для инъекции зависимости, ошибка не будет выброшена.
Дополнительную информацию можно найти по ссылке:
https://www.concretepage.com/spring/spring-autowired-annotation#required-false
Однако @Inject не требует атрибута required=false, так как ошибка не произойдет, если зависимость не найдена.
Почему поле с @Autowired в Spring оказывается null?
Spring: @Component против @Bean
Что такое JavaBean?
Eclipse/Java: не работает автозавершение кода
Загрузка JDK Java на Linux через wget приводит к отображению страницы лицензии вместо установки