IoC-контейнер Spring управляет одним или несколькими бинами. Эти бины создаются с помощью конфигурационных метаданных, которые вы предоставляете контейнеру (например, в виде XML -определений <bean/>).
В самом контейнере эти определения бинов представлены в виде объектов BeanDefinition, которые содержат (среди прочей информации) следующие метаданные:
-
Полное имя класса с указанием пакета: как правило, это фактический класс реализации определяемого бина.
-
Элементы поведенческой конфигурации бина, которые определяют то, как бин должен вести себя в контейнере (область действия, обратные вызовы жизненного цикла и так далее).
-
Ссылки на другие бины, которые необходимы для его работы. Эти ссылки также называются взаимодействующими объектами (collaborators) или зависимостями (dependencies).
-
Другие параметры конфигурации, которые необходимо установить во вновь созданном объекте, например, предельный размер пула или количество соединений, используемых в бине, который управляет пулом соединений.
Эти метаданные преобразуются в набор свойств, которые составляют определение каждого бина. В следующей таблице описаны эти свойства:
| Свойство | Объясняется в... |
|---|---|
| Класс |
|
| Имя |
Именование бинов |
| Область применения |
|
| Аргументы конструктора |
|
| Свойства |
|
| Режим автоматического обнаружения и связывания |
Взаимодействующие объекты с автоматическим обнаружением и связыванием |
| Режим отложенной инициализации |
|
| Метод инициализации |
|
| Метод уничтожения |
В дополнение к определениям бинов, которые содержат информацию о том, как создать конкретный бин, реализации ApplicationContext также позволяют регистрировать существующие объекты, которые создаются вне контейнера (пользователями). Это возможно осуществить путем обращения к BeanFactory ApplicationContext через метод getBeanFactory(), который возвращает реализацию DefaultListableBeanFactory. DefaultListableBeanFactory поддерживает данную регистрацию через методы registerSingleton(..) и registerBeanDefinition(..). Однако типичные приложения работают исключительно с бинами, определенными с помощью стандартных метаданных определения бинов.
Метаданные бинов и экземпляры-одиночки, предоставляемые вручную, должны быть зарегистрированы как можно скорее, чтобы контейнер мог правильно обработать их во время автоматического обнаружения и связывания и других этапов интроспекции. Хотя переопределение существующих метаданных и существующих экземпляров-одиночек и поддерживается в некоторой степени, регистрация новых бинов во время выполнения (одновременно с прямым доступом к фабрике) официально не поддерживается и может привести к исключениям одновременного доступа, несовместимому состоянию в контейнере бинов или к обоим этим исключениям.
Именование бинов
Каждый бин имеет один или несколько идентификаторов. Эти идентификаторы должны быть уникальными в пределах контейнера, в котором находится бин. Бины обычно имеют только один идентификатор. Однако, если требуется более одного, дополнительные можно считать псевдонимами.
В конфигурационных метаданных на основе XML используется атрибут id, атрибут name или оба для задания идентификаторов бина. Атрибут id позволяет задать только один идентификатор. Обычно эти имена являются буквенно-цифровыми ('myBean', 'someService' и т.д.), но они могут содержать и специальные символы. Если вы хотите ввести другие псевдонимы для бина, то также можете задать их в атрибуте name, отделив запятой (,), точкой с запятой (;) или пробелом. Историческая справка: в версиях до Spring 3.1 атрибут id был определен как тип xsd:ID, что ограничивало применение символов. Начиная с версии 3.1, он определяется как тип xsd:string. Обратите внимание, что уникальность id бина все еще обеспечивается контейнером, но уже не анализаторами XML.
Не нужно указывать name или id для бина. Если явно не задать name или id, контейнер сгенерирует уникальное имя для этого бина. Однако если вы хотите ссылаться на этот бин по имени, используя элемент ref или поиск в стиле локатора служб (Service Locator), то должны указать имя. Мотивы отказа от указания имени связаны с использованием внутренних бинов и взаимодействующих объектов с автоматическим обнаружением и связыванием.
java.beans.Introspector.decapitalize (который Spring использует здесь).
Присвоение псевдонима бину вне определения бина
В самом определении бина можно указать более одного имени для бина, используя комбинацию из одного имени, указанного атрибутом id, и любого количества других имен в атрибуте name. Эти имена могут быть эквивалентными псевдонимами одного и того же бина и полезны в некоторых ситуациях, например, когда каждый компонент в приложении ссылается на общую зависимость, используя имя бина, специфичное для этого компонента.
Однако задание всех псевдонимов, в которых фактических определен бин, не всегда является достаточным. Иногда желательно ввести псевдоним для бина, который определен в другом месте. Это обычно имеет место в больших системах, где конфигурация разделена между каждой подсистемой, а каждая подсистема имеет свой собственный набор определений объектов. В конфигурационных метаданных на основе XML для этого можно использовать элемент <alias/>. В следующем примере показано, как это сделать:
<alias name="fromName" alias="toName"/>
В этом случае бин (в том же контейнере) с именем fromName - после использования этого определения псевдонима - может упоминаться как toName.
Например, конфигурационные метаданные для подсистемы A могут ссылаться на источник данных DataSource под именем subsystemA-dataSource. Конфигурационные метаданные для подсистемы B могут ссылаться на источник данных DataSource под именем subsystemB-dataSource. При создании основного приложения, использующего обе эти подсистемы, основное приложение обращается к источнику данных DataSource под именем myApp-dataSource. Чтобы все три имени ссылались на один и тот же объект, вы можете добавить следующие определения псевдонимов в конфигурационные метаданные:
<alias name="myApp-dataSource" alias="subsystemA-dataSource"/>
<alias name="myApp-dataSource" alias="subsystemB-dataSource"/>
Теперь каждый компонент и основное приложение могут обращаться к dataSource через имя, которое является уникальным и гарантированно не будет конфликтовать ни с каким другим определением (эффективно создавая пространство имен), но при этом они обращаются к одному и тому же бину.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ