Чем @Autowired отличается от @Resource?java-40

Оба аннотации @Autowired и @Resource используются для внедрения зависимостей (dependency injection) в Spring, но они имеют разные особенности и поведение. Давайте разберем их отличия подробно.

1. Происхождение

  • @Autowired: Это аннотация Spring Framework. Она является частью Spring и используется для автоматического связывания бинов.
  • @Resource: Это аннотация из стандарта JSR-250 (Java Specification Request). Она не является частью Spring, но поддерживается Spring для совместимости с другими Java EE контейнерами.

2. Механизм внедрения

  • @Autowired: Использует тип (by type) для внедрения зависимостей. Если Spring находит несколько бинов одного типа, он может использовать @Qualifier для уточнения, какой именно бин нужно внедрить.
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;

public class MyService {
    @Autowired
    @Qualifier("myRepository")
    private MyRepository repository;
}
  • @Resource: Использует имя (by name) для внедрения зависимостей. Если имя не указано, оно будет искать бин по типу.
import javax.annotation.Resource;

public class MyService {
    @Resource(name = "myRepository")
    private MyRepository repository;
}

3. Обязательность

  • @Autowired: По умолчанию является обязательной (required = true). Если бин не найден, Spring выбросит исключение. Это поведение можно изменить, установив required = false.
import org.springframework.beans.factory.annotation.Autowired;

public class MyService {
    @Autowired(required = false)
    private MyRepository repository;
}
  • @Resource: Также является обязательной по умолчанию. Если бин не найден, будет выброшено исключение. Однако, в отличие от @Autowired, здесь нет возможности изменить это поведение через аннотацию.

4. Поддержка полей, сеттеров и конструкторов

  • @Autowired: Может использоваться для внедрения через поля, сеттеры и конструкторы.
import org.springframework.beans.factory.annotation.Autowired;

public class MyService {
    private MyRepository repository;

    @Autowired
    public MyService(MyRepository repository) {
        this.repository = repository;
    }
}
  • @Resource: Обычно используется для внедрения через поля и сеттеры. Не поддерживает внедрение через конструкторы.
import javax.annotation.Resource;

public class MyService {
    @Resource
    private MyRepository repository;

    @Resource
    public void setRepository(MyRepository repository) {
        this.repository = repository;
    }
}

5. Поддержка @Qualifier

  • @Autowired: Может использоваться вместе с @Qualifier для уточнения, какой именно бин нужно внедрить, если есть несколько бинов одного типа.
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;

public class MyService {
    @Autowired
    @Qualifier("myRepository")
    private MyRepository repository;
}
  • @Resource: Использует атрибут name для указания имени бина, что делает использование @Qualifier излишним.
import javax.annotation.Resource;

public class MyService {
    @Resource(name = "myRepository")
    private MyRepository repository;
}

Резюмируем

  • @Autowired является аннотацией Spring и использует тип для внедрения зависимостей. Она поддерживает внедрение через поля, сеттеры и конструкторы, а также может быть настроена как необязательная.
  • @Resource является частью стандарта JSR-250 и использует имя для внедрения зависимостей. Она поддерживает внедрение через поля и сеттеры, но не через конструкторы, и всегда является обязательной.

Выбор между @Autowired и @Resource зависит от конкретных требований вашего проекта и предпочтений разработчика. Если вам нужно больше гибкости и интеграция с Spring, используйте @Autowired. Если важна совместимость с другими Java EE контейнерами, выбирайте @Resource.