Spring IoC контейнер: зависимости и конфигурация в деталях, коллекции

Элементы <list/>, <set/>, <map/> и <props/> устанавливают свойства и аргументы типов Java Collection: List, Set, Map и Properties соответственно. В следующем примере показано, как их использовать:

<bean id="moreComplexObject" class="example.ComplexObject">
    <!-- приводит к вызову setAdminEmails(java.util.Properties) -->
    <property name="adminEmails">
        <props>
            <prop key="administrator">administrator@example.org</prop>
            <prop key="support">support@example.org</prop>
            <prop key="development">development@example.org</prop>
        </props>
    </property>
    <!-- приводит к вызову setSomeList(java.util.List) -->
    <property name="someList">
        <list>
            <value>a list element followed by a reference</value>
            <ref bean="myDataSource" />
        </list>
    </property>
    <!-- приводит к вызову setSomeMap(java.util.Map) -->
    <property name="someMap">
        <map>
            <entry key="an entry" value="just some string"/>
            <entry key ="a ref" value-ref="myDataSource"/>
        </map>
    </property>
    <!-- приводит к вызову setSomeSet(java.util.Set) -->
    <property name="someSet">
        <set>
            <value>just some string</value>
            <ref bean="myDataSource" />
        </set>
    </property>
</bean>

Значением ключа или значения карты или заданного значения также может быть любой из следующих элементов:

bean | ref | idref | list | set | map | props | value | null

Объединение коллекций

Контейнер Spring также поддерживает объединение коллекций. Разработчик приложения может определить родительский элемент <list/>, <map/>, <set/> или <props/> и иметь дочерние элементы <list/>, <map/>, <set/> или <props/> наследовать и переопределять значения из родительской коллекции. То есть значения дочерней коллекции являются результатом слияния элементов родительской и дочерней коллекций с переопределением значений дочерних элементов коллекции, указанных в родительской коллекции.

В следующем примере демонстрируется объединение коллекций:

<beans>
    <bean id="parent" abstract="true" class="example.ComplexObject">
        <property name="adminEmails">
            <props>
                <prop key="administrator">administrator@example.com</prop>
                <prop key="support">support@example.com</prop>
            </props>
        </property>
    </bean>
    <bean id="child" parent="parent">
        <property name="adminEmails">
            <!-- объединение указано в определении дочерней коллекции -->
            <props merge="true">
                <prop key="sales">sales@example.com</prop>
                <prop key="support">support@example.co.uk</prop>
            </props>
        </property>
    </bean>
<beans>

Обратите внимание на использование атрибута merge=true в элементе <props/> свойства adminEmails определения дочернего компонента. Когда дочерний компонент разрешается и создается экземпляром в контейнере, результирующий экземпляр имеет коллекцию свойств adminEmails, в которой содержится результат объединения дочерней коллекции adminEmails с коллекцией родительского adminEmails. Следующий листинг показывает результат:

administrator=administrator@example.com
sales=sales@example.com
support=support@example.co.uk

Набор значений дочерней коллекции Properties наследует все элементы свойства от родительского <props/>, а значение дочернего элемента для значения поддержки переопределяет значение в родительской коллекции.

Такое поведение объединения аналогично применяется к типам коллекций <list/>, <map/> и <set/>. В конкретном случае элемента <list/> сохраняется семантика, связанная с типом коллекции List (то есть понятие упорядоченной коллекции значений). Значения родителя предшествуют всем значениям дочернего списка. В случае типов коллекций Map, Set и Properties упорядочение не существует. Следовательно, семантика упорядочения не действует для типов коллекции, которые лежат в основе связанных типов реализации Map, Set и Properties, которые контейнер использует внутри.

Ограничения объединения коллекций

Вы не можете объединять разные типы коллекций (например, Map и List). Если вы попытаетесь это сделать, выдается соответствующее исключение. Атрибут слияния должен быть указан в нижнем унаследованном дочернем определении. Указание атрибута слияния в определении родительской коллекции является излишним и не приводит к желаемому слиянию.

Сильно типизированная коллекция

С введением универсальных типов в Java 5 вы можете использовать строго типизированные коллекции. То есть можно объявить тип Collection так, чтобы он мог содержать только (например) элементы String. Если вы используете Spring для добавления зависимостей в строго типизированную коллекцию в bean-компонент, вы можете воспользоваться преимуществами поддержки преобразования типов в Spring, так что элементы ваших строго типизированных экземпляров Collection преобразуются в соответствующий тип перед добавлением в Collection. Следующее определение Java-класса и bean-компонента показывает, как это сделать:

Java

public class SomeClass {

    private Map accounts;

    public void setAccounts(Map accounts) {
        this.accounts = accounts;
    }
}

Kotlin

class SomeClass {
    lateinit var accounts: Map
}

<beans>
    <bean id="something" class="x.y.SomeClass">
        <property name="accounts">
            <map>
                <entry key="one" value="9.99"/>
                <entry key="two" value="2.75"/>
                <entry key="six" value="3.99"/>
            </map>
        </property>
    </bean>
</beans>

Когда свойство account объекта Bean-объекта подготовлено для внедрения, общая информация о типе элемента строго типизированной Map<String, Float> доступна для отражения. Таким образом, инфраструктура преобразования типов в Spring распознает различные элементы-значения как имеющие тип Float, а строковые значения (9.99, 2.75 и 3.99) преобразуются в фактический тип Float.


Читайте также:


Комментарии

Популярные сообщения из этого блога

Методы класса Object в Java

Как получить текущий timestamp в Java

Основные опции JVM для повышения производительности и отладки