Понимание использования Spring @Autowired

Я читаю справочную документацию весны 3.0.x, чтобы понять аннотацию Spring Autowired:

3.9.2 @Autowired и @Inject

Я не могу понять приведенные ниже примеры. Нужно ли нам что-то делать в XML, чтобы он работал?

ПРИМЕР 1

public class SimpleMovieLister { private MovieFinder movieFinder; @Autowired public void setMovieFinder(MovieFinder movieFinder) { this.movieFinder = movieFinder; } // ... } 

ПРИМЕР 2

 public class MovieRecommender { private MovieCatalog movieCatalog; private CustomerPreferenceDao customerPreferenceDao; @Autowired public void prepare(MovieCatalog movieCatalog, CustomerPreferenceDao customerPreferenceDao) { this.movieCatalog = movieCatalog; this.customerPreferenceDao = customerPreferenceDao; } // ... } 

Как можно использовать два classа для реализации одного и того же интерфейса и использования одного и того же classа?

Пример:

 class Red implements Color class Blue implements Color class myMainClass{ @Autowired private Color color; draw(){ color.design(); } } 

Какой метод проектирования будет называться? Как я могу убедиться, что метод проектирования classа Red будет вызываться, а не Blue?

@Autowired аннотация позволяет пропустить конфигурации в другом месте, что нужно вводить, и просто делает это для вас. Предполагая, что ваш пакет com.mycompany.movies вы должны поместить этот тег в свой XML-файл (контекстный файл приложения):

  

Этот тег будет выполнять автоматическое сканирование. Предполагая, что каждый class, который должен стать bean-компонентом, аннотируется с помощью правильной annotations, такой как @Component (для простого компонента) или @Controller (для управления сервлетом) или @Repository (для classов DAO ), и эти classы находятся где-то под пакетом com.mycompany.movies , Spring найдет все это и создаст компонент для каждого из них. Это делается при 2-х проверках classов – в первый раз, когда он просто ищет classы, которые должны стать компонентом, и отображает инъекции, которые он должен выполнять, а на втором сканировании он вводит компоненты. Конечно, вы можете определить свои компоненты в более традиционном XML-файле или в classе @Configuration (или любой комбинации из трех).

@Autowired сообщает Spring, где должна произойти инъекция. Если вы положили его на метод setMovieFinder он понимает (по set префикса + @Autowired annotation), что необходимо @Autowired компонент. Во втором сканировании Spring ищет компонент типа MovieFinder , и если он находит такой компонент, он вводит его в этот метод. Если он найдет два таких компонента, вы получите Exception . Чтобы избежать Exception , вы можете использовать аннотацию @Qualifier и указать, какой из двух компонентов будет вводить следующим образом:

 @Qualifier("redBean") class Red implements Color { // Class code here } @Qualifier("blueBean") class Blue implements Color { // Class code here } 

Или, если вы предпочитаете объявлять компоненты в своем XML, это выглядит примерно так:

   

В объявлении @Autowired вам нужно также добавить @Qualifier чтобы указать, какая из двух цветовых @Qualifier для инъекции:

 @Autowired @Qualifier("redBean") public void setColor(Color color) { this.color = color; } 

Если вы не хотите использовать две annotations ( @Autowired и @Qualifier ), вы можете использовать @Resource для объединения этих двух:

 @Resource(name="redBean") public void setColor(Color color) { this.color = color; } 

@Resource (вы можете прочитать некоторые дополнительные данные об этом в первом комментарии к этому ответу) избавляет вас от использования двух аннотаций, и вместо этого вы используете только один.

Я просто добавлю еще два комментария:

  1. Хорошей практикой было бы использовать @Inject вместо @Autowired потому что он не зависит от Spring и является частью стандарта JSR-330 .
  2. Другой хорошей практикой было бы поставить @Inject / @Autowired на конструктор вместо метода. Если вы поместите его в конструктор, вы можете проверить, что введенные bean-компоненты не являются нулевыми и не работают быстро, когда вы пытаетесь запустить приложение и избегаете исключения NullPointerException когда вам нужно фактически использовать компонент.

Итак, @Autowired итог: @Autowired annotation избавляет вас от необходимости @Autowired проводку самостоятельно в XML-файле (или любым другим способом) и просто находит для вас то, что нужно вводить туда и делает это для вас.

Обновление . Чтобы завершить изображение, я создал новый вопрос о classе @Configuration .

Ничто в этом примере не говорит о том, что «classы реализуют один и тот же интерфейс». MovieCatalog – это тип, а CustomerPreferenceDao – другой тип. Весна может легко рассказать им обособленно.

Весной 2.x проводка бобов в основном происходила с помощью идентификаторов или имен bean-компонентов. Это все еще поддерживается Spring 3.x, но часто у вас будет один экземпляр компонента с определенным типом – большинство сервисов – это одиночные. Создание имен для них утомительно. Поэтому Spring начала поддерживать «autwire by type».

То, что показывают примеры, – это различные способы, которыми вы можете использовать для добавления компонентов в поля, методы и конструкторы.

XML уже содержит всю информацию, необходимую Spring, поскольку вам нужно указать полное имя classа в каждом компоненте. Вы должны быть немного осторожны с интерфейсами, хотя:

Это автоподключение не удастся:

  @Autowired public void prepare( Interface1 bean1, Interface1 bean2 ) { ... } 

Поскольку Java не сохраняет имена параметров в байтовом коде, Spring больше не может различать эти два компонента. Исправлено использование @Qualifier :

  @Autowired public void prepare( @Qualifier("bean1") Interface1 bean1, @Qualifier("bean2") Interface1 bean2 ) { ... } 

Да, вы можете настроить xml-файл контекста сервлета Spring, чтобы определить ваши компоненты (то есть classы), чтобы он мог выполнять автоматическую инъекцию для вас. Однако имейте в виду, что вам нужно делать другие конфигурации, чтобы запустить Spring и работать, и лучший способ сделать это – следовать руководству.

Как только у вас настроена настройка Spring, вы можете сделать следующее в вашем XML-файле контекста Spring сервлета для примера 1 выше, чтобы работать (пожалуйста, замените имя пакета com.movies на то, что истинное имя пакета, и если это сторонний участник class, то убедитесь, что соответствующий файл jar находится в пути к classам):

  

или если class MovieFinder имеет конструктор с примитивным значением, то вы могли бы что-то вроде этого,

    

или если class MovieFinder имеет конструктор, ожидающий другого classа, то вы можете сделать что-то вроде этого,

    

… где « otherBeanRef » – это еще один компонент, который имеет ссылку на ожидаемый class.

@Autowired

Пусть Spring автоматически подключит другие бобы к вашим classам с помощью @Autowired annotations.

 @Service public class CompanyServiceImpl implements CompanyService { @Autowired private CompanyDAO companyDAO; ... } 

Spring Annotation Tip Весенние бобы могут быть связаны по имени или по типу. @Autowire по умолчанию является инъекцией типа. @Qualifier spring annotation может использоваться для дальнейшей тонкой настройки автоустановки. Аннотацию @Resource (javax.annotation.Resource) можно использовать для проводки по имени. Бобы, которые сами определяются как тип коллекции или карты, не могут быть введены через @Autowired, поскольку сопоставление типов не подходит для них. Используйте @Resource для таких компонентов, ссылаясь на конкретную коллекцию или картографический компонент по уникальному имени

  • Проверка активного подключения к Интернету Android
  • Android java.lang.NoClassDefFoundError: org.jsoup.Jsoup
  • Является ли Java оценкой оставшихся условий после того, как известен логический результат?
  • Загрузить профиль Chrome с помощью Selenium WebDriver с помощью java
  • Окно оверлей системы Android
  • Состояние флажка ListView Viewholder
  • Преобразовать строку в строку, разделенную запятыми, в java
  • Что означает '->' (стрелка) в графе зависимостей gradleиента?
  • Я хотел бы установить мои переменные в верхней части моего classа, а не в методе
  • Java выполняет команду с пробелом в пути
  • Неполадка контекста ошибки сборки IntelliJ
  • Давайте будем гением компьютера.