Контейнер Spring может автоматически устанавливать отношения между взаимодействующими бинами. Вы можете дать Spring автоматически выполнить разрешение взаимодействующих объектов (других бинов) для вашего бина, просматривая содержимое ApplicationContext. Автоматическое обнаружение и связывание имеет следующие преимущества:

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

  • Автоматическое обнаружение и связывание позволяет обновлять конфигурацию по мере развития ваших объектов. Например, если вам нужно добавить зависимость к классу, эта зависимость может быть удовлетворена автоматически, без необходимости изменять конфигурацию. Таким образом, автоматическое обнаружение и связывание может быть особенно полезно во время разработки, что не отменяет возможность перехода к явному связыванию, когда кодовая база станет стабильной.

При использовании конфигурационных метаданных на основе XML вы можете задать режим автоматического связывания в определении бина с помощью атрибута autowire элемента <bean/>. Функциональность автоматического обнаружения и связывания имеет четыре режима. Вы задаете автоматическое обнаружение и связывание для каждого бина и, таким образом, можете выбирать, какие из них автоматически связывать. В следующей таблице описаны четыре режима автоматического обнаружения и связывания:

Таблица 2. Режимы автоматического обнаружения и связывания
Режим Пояснение

no

(По умолчанию) Без автоматического обнаружения и связывания. Ссылки на бины должны быть определены элементами ref. Изменение параметра по умолчанию не рекомендуется для больших развертываний, поскольку явное указание взаимодействующих объектов обеспечивает больший контроль и ясность. В некоторой степени он документирует структуру системы.

byName

Автоматическое обнаружение и связывание по имени свойства. Spring ищет бин с тем же именем, что и свойство, которое должно быть автоматически обнаружено и связано. Например, если в определении бина содержится инструкция на автоматическое обнаружение и связывание по имени и свойство master (то есть имеет метод setMaster(..)), Spring ищет определение бина с именем master и использует его для задания свойства.

byType

Позволяет свойству быть автоматически обнаруженным и связанным, если в контейнере существует ровно один бин с данным типом свойства. Если существует более одного, то генерируется критическое исключение, которое указывает, что нельзя использовать режим автоматического обнаружения и связывания byType для этого бина. Если подходящих бинов нет, ничего не произойдет (свойство не будет задано).

constructor

Аналогично byType, но применяется к аргументам конструктора. Если в контейнере нет ровно одного бина c типом аргумента конструктора, то возникает критическая ошибка.

С помощью режима автоматического обнаружения и связывания byType или constructor можно связывать массивы и типизированные коллекции. В таких случаях все компоненты-кандидаты для автоматического обнаружения и связывания, находящиеся в контейнере и соответствующие ожидаемому типу, предоставляются для удовлетворения зависимости. Вы можете осуществлять автоматический поиск и связывание экземпляров Map со строгой типизацией, если ожидаемый тип ключа - String. Значения автоматически связываемого экземпляра Map состоят из всех экземпляров бинов, соответствующих ожидаемому типу, а ключи экземпляра Map содержат соответствующие имена бинов.

Ограничения и недостатки автоматического обнаружения и связывания

Автоматическое обнаружение и связывание работает лучше всего, если его использовать последовательно в рамках всего проекта. Если автоматическое обнаружение и связывание вообще не используется, разработчикам может быть сложно использовать его для связывания только одного или двух определений бина.

Рассмотрим ограничения и недостатки автоматического обнаружения и связывания:

  • Явные зависимости в property и constructor-arg всегда переопределяют автоматическое обнаружение и связывание. Нельзя автоматически связывать простые свойства, такие как примитивы, Strings и Classes (и массивы таких простых свойств). Данное ограничение является преднамеренным.

  • Автоматическое обнаружение и связывание является менее точным, чем явное связывание. Хотя, как отмечалось в предыдущей таблице, Spring старается не прибегать к предугадыванию в случае неоднозначности, которое может привести к неожиданным результатам. Взаимосвязи между вашими объектами, управляемыми Spring, больше не документируются в явном виде.

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

  • Множественные определения бинов в контейнере могут соответствовать типу, заданному устанавливающим методом или аргументом конструктора для автоматического обнаружения и связывания. Для массивов, коллекций или экземпляров Map это не обязательно является проблемой. Однако в отношении зависимостей, для которых ожидается некое единственное значение, эта двусмысленность не разрешается произвольно. Если уникальное определение бина недоступно, генерируется исключение.

В последнем случае у вас есть несколько вариантов:

  • Откажитесь от автоматического обнаружения и связывания в пользу явного связывания.

  • Избегайте автоматического обнаружения и связывания для определения бина, задав его атрибуты autowire-candidate в false

  • Назначьте одно определение бина в качестве основного компонента-кандидата, задав атрибут primary элемента <bean/> как true.

  • Реализуйте более тонкий контроль, доступный при конфигурации на основе аннотаций.

Исключение бина из метода автоматического обнаружения и связывания

В отношении каждого бина можно исключить его из метода автоматического обнаружения и связывания. В XML-формате Spring задайте атрибут autowire-candidate элемента <bean/> как false. Контейнер сделает это конкретное определение бина недоступным для инфраструктуры автоматического обнаружения и связывания (включая конфигурации в стиле аннотации, такие как @Autowired).

Атрибут autowire-candidate предназначен только для воздействия на метод автоматического обнаружения и связывания на основе типа. Он не влияет на явные ссылки по имени, которые разрешаются, даже если указанный бин не помечен как компонент-кандидат для автоматического обнаружения и связывания. Как следствие, автоматическое обнаружение и связывание по имени, тем не менее, внедряет бин, если имя совпадает.

Вы также можете ограничить компоненты-кандидаты на автоматическое обнаружение и связывания на основе сопоставления шаблонов с именами бинов. Элемент верхнего уровня <bean/> принимает один или несколько шаблонов в своем атрибуте default-autowire-candidates. Например, чтобы ограничить статус компонента-кандидата на автоматическое обнаружение и связывание любым бином, имя которого заканчивается на Repository, подставьте значение *Repository. Чтобы передать несколько шаблонов, задайте их в списке с отделением запятыми. Явное значение true или false для атрибута autowire-candidate в определении бина всегда более приоритетное. Для таких бинов правила соответствия шаблону не применяются.

Данные методы полезны в случае использования бинов, которые вам никогда не потребуется внедрять в другие бины с помощью автоматического обнаружения и связывания. Это не означает, что исключенный бин не может быть сам сконфигурирован с помощью автоматического обнаружения и связывания. Скорее, сам бин не является компонентом-кандидатом на автоматическое обнаружение и связывание других бинов.