Главная » Spring » Внедрение коллекций Spring

0

До сих пор демонстрировались особенности определения простых значений свойств (с помощью атрибута value) и ссылок на другие компоненты (с помощью атрибута ref). Однако атрибуты value и ref можно использовать, только когда свойства компонента содержат единственное значение. А возможно ли с помощью Spring инициа- лизировать свойства, имеющие множество значений, что, если свой- ство является коллекцией значений?

Фреймворк Spring предлагает четыре типа элементов определе- ния коллекций, которые пригодятся для конфигурирования значе- ний, являющихся коллекциями. В табл. 2.3 приводится список этих элементов и описывается, для чего они предназначены.

Элементы <list> и <set> можно использовать для настройки свойств, которые являются массивами или одной из реализаций java.util.Collection. Как будет показано чуть ниже, фактическая реализация коллекции, используемая для определения свойства,

имеет некоторое значение при выборе между элементами <list>  и

<set>. Оба элемента могут использоваться почти взаимозаменяемо, со свойствами любого типа java.util.Collection.

Таблица 2.3. Подобно тому как в Java имеется несколько видов коллекций, фреймворк Spring так же позволяет внедрение нескольких видов коллекций

Элемент- коллекция

Назначение

<list>

Связывание списка значений, допускаются повторяющиеся значения

<set>

Связывание множества значений, гарантирует отсутствие повторяющихся значений

<map>

Связывание коллекций пар имя/значение, где имя и значение могут быть значениями любых типов

<props>

Связывание коллекций пар имя/значение, где имя и значение должны имеет строковый тип (String)

Что касается элементов <map> и <props>, они соответствуют кол- лекциям с интерфейсами java.util.Map и java.util.Properties соответ- ственно. Эти типы коллекций можно использовать, когда требуется коллекция, состоящая из пар ключ/значение. Ключевым отличием между ними состоит в том, что при использовании элемента <props> ключи и значения в коллекции должны быть значениями типа String, тогда как при использовании элемента <map> ключи и значения могут быть любых типов.

А теперь, чтобы продемонстрировать возможность связывания коллекций в Spring, поприветствуем Хэнка на сцене «Spring Idol». Особенность таланта Хэнка в том, что он – человек-оркестр. Как и Кенни, Хэнк способен играть на нескольких инструментах, но Хэнк может играть на нескольких инструментах одновременно. Хэнк определен классом OneManBand, как показано в листинге 2.8.

Листинг 2.8. Исполнитель, который является человеком-оркестром

package com.springinaction.springidol; import   java.util.Collection;

public  class  OneManBand  implements  Performer  { public OneManBand() {

}

public void perform() throws PerformanceException { for (Instrument instrument : instruments) {

instrument.play();

}

}

private Collection<Instrument> instruments;

public   void   setInstruments(Collection<Instrument>   instruments)   { this.instruments  =  instruments;  // Внедрение  коллекции  инструментов

}

}

Как показано в листинге 2.8, во время выступления объект OneManBand выполняет итерации по коллекции инструментов. Наи- более важно здесь, что коллекция инструментов внедряется через метод setInstruments(). Посмотрим, как Spring сможет обеспечить Хэнка своей коллекцией инструментов.

Внедрение списков, множеств и массивов

Чтобы передать Хэнку коллекцию инструментов для выступле- ния, воспользуемся элементом <list>:

<bean  id="hank"

class="com.springinaction.springidol.OneManBand">

<property name="instruments">

<list>

<ref  bean="guitar"  />

<ref bean="cymbal" />

<ref bean="harmonica" />

</list>

</property>

</bean>

Элемент <list> содержит одно или более значений. Здесь эле- менты <ref> используются для определения ссылок на другие ком- поненты в контексте Spring и передают Хэнку гитару, цимбалы и губную гармошку. Однако внутри элемента <list> можно также использовать другие элементы, определяющие значения, включая

<value>, <bean> и <null/>. В действительности элемент <list> может содержать в себе другие элементы <list> как элементы многомер- ных списков.

В листинге 2.8 свойство instruments класса OneManBand имеет тип java.util.Collection, и для сохранения в нем значений типа Instrument используются обобщения Java 5. Но элемент <list> может приме- няться к свойствам, которые могут быть любыми реализациями java.util.Collection или массивом. Другими словами, элемент <list> можно было бы использовать, даже если свойство instruments было бы объявлено как:

java.util.List<Instrument>  instruments;

или как:

Instrument[] instruments;

Аналогично для связывания свойств, являющихся коллекциями или массивами можно использовать элемент <set>:

<bean  id="hank"

class="com.springinaction.springidol.OneManBand">

<property name="instruments">

<set>

<ref  bean="guitar"  />

<ref bean="cymbal" />

<ref bean="harmonica" />

<ref bean="harmonica" />

</set>

</property>

</bean>

Как уже говорилось, элементы <list> и <set> могут использоваться для связывания значений с любой реализацией java.util.Collection или массивом. Если свойство имеет тип java.util.Set, это еще не означает, что для его инициализации следует обязательно исполь- зовать элемент <set>. Даже при том, что возможность инициализи- ровать свойство типа java.util.List с помощью элемента <set> мо- жет показаться странной, в действительности это вполне допустимо. В этом случае гарантируется уникальность элементов списка List.

Связывание отображений

Когда выступает человек-оркестр (OneManBand), звук каждого ин- струмента выводится методом perform() в процессе выполнения ите- раций по коллекции инструментов. Но предположим, что мы также

хотим видеть, какой инструмент соответствует каждому извлекае- мому звуку. Чтобы реализовать это, изменим класс OneManBand, как показано в листинге 2.9.

Листинг 2.9. Преобразование коллекции инструментов класса OneManBand

в отображение (Map)

package com.springinaction.springidol;

import java.util.Map;

import    com.springinaction.springidol.Instrument;

import  com.springinaction.springidol.PerformanceException; import    com.springinaction.springidol.Performer;

public  class  OneManBand  implements  Performer  { public OneManBand() {

}

public void perform() throws PerformanceException { for  (String  key  : instruments.keySet())  {

System.out.print(key  +  "  : ");

Instrument  instrument  =  instruments.get(key); instrument.play();

}

}

private  Map<String,  Instrument>  instruments;

public  void  setInstruments(Map<String,  Instrument>  instruments)  { this.instruments = instruments;    // Внедрение инструментов в виде

}                                                                   // отображения  (Map)

}

В новой версии класса OneManBand свойство instruments имеет тип отображения java.util.Map, каждый член которого имеет ключ типа String и значение типа Instrument. Так как члены отображения пред- ставлены парами ключ/значение, простых элементов <list> или <set> будет недостаточно для связывания свойства.

Вместо этого для конфигурирования свойства instruments в сле- дующем объявлении компонента hank используется элемент <map>:

<bean  id="hank"  class="com.springinaction.springidol.OneManBand">

<property name="instruments">

<map>

<entry key="GUITAR" value-ref="guitar" />

<entry key="CYMBAL" value-ref="cymbal" />

<entry key="HARMONICA" value-ref="harmonica" />

</map>

</property>

</bean>

Элемент <map> объявляет значение типа java.util.Map. Каждый элемент <entry> определяет один элемент отображения. В предыду- щем примере атрибут key определяет ключ элемента отображения, а атрибут value-ref – значение элемента отображения как ссылку на другой компонент внутри контекста Spring.

В нашем примере атрибут key используется для определения строкового ключа, а атрибут value-ref – для определения ссылоч- ного значения, однако в действительности каждый элемент <entry> имеет по два атрибута для определения ключа и значения элемента отображения. Эти атрибуты перечислены в табл. 2.4.

Элемент <map> – это единственный способ внедрения пар ключ/ значение в свойства компонента, когда один из объектов не является строкой. Посмотрим, как использовать элемент <props> для настрой- ки отображения строка в строку.

Таблица 2.4. Элемент <entry> в элементе <map> позволяет определить ключ и значение элемента отображения, каждый из которых может быть простым значением

или ссылкой на другой компонент

Атрибут

Назначение

key

Определяет ключ элемента отображения как строку

key-ref

Определяет ключ элемента отображения как ссылку на компонент в контексте Spring

value

Определяет значение элемента отображения как строку

value-ref

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

Внедрение  свойств-коллекций

При описании коллекции Map значений для свойства instrument в объекте OneManBand значение в каждом элементе отображения бы- ло определено с помощью атрибута value-ref. Это обусловлено тем, что каждый элемент отображения в конечном счете является другим компонентом в контексте Spring.

Но если при формировании отображения обнаружится, что ключи и значения в нем являются строками, возможно, предпочтительнее

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

Для иллюстрации представьте, что вместо коллекции строк и ссы- лок на компоненты в свойство объекта OneManBand внедряется отобра- жение строки в строку Java.util.Properties. Новое свойство instruments в этом случае можно было бы изменить, как показано ниже.

private  Properties  instruments;

public  void  setInstruments(Properties  instruments)  { this.instruments   =   instruments;

}

Чтобы связать звуки, издаваемые инструментами, со свойством instruments, в этом случае можно использовать элемент <props>, как показано в следующем объявлении компонента hank:

<bean  id="hank"  class="com.springinaction.springidol.OneManBand">

<property name="instruments">

<props>

<prop key="GUITAR">STRUM STRUM STRUM</prop>

<prop key="CYMBAL">CRASH CRASH CRASH</prop>

<prop  key="HARMONICA">HUM  HUM  HUM</prop>

</props>

</property>

</bean>

Элемент <props> создает отображение типа java.util.Properties, каждый член которого определяется элементом <prop>. Каждый элемент <prop> имеет атрибут key, определяющий ключ члена ото- бражения Properties, а значение определяется содержимым элемента

<prop>. В нашем примере элемент с ключом «GUITAR» имеет значе- ние «STRUM STRUM STRUM».

Это, пожалуй, самый сложный для обсуждения элемент конфигу- рации Spring, потому что термин «property» (свойство) сильно пере- гружен. Здесь важно придерживаться следующих правил:

#  <property> – это элемент для внедрения значения или ссылки

на компонент в «обычное» свойство компонента;

# <props> – это элемент для определения коллекций типа java. util.Properties;

# <prop> – это элемент для определения члена коллекции <props>.

Теперь нам известно несколько способов внедрения значений в свойства компонентов. Мы попробовали внедрять простые значе- ния, ссылки на другие компоненты и коллекции. А сейчас посмот- рим, как внедрить в свойство компонента пустое значение.

Источник:   Уоллс К., Spring в действии. – М.: ДМК Пресс, 2013. – 752 с.: ил.

По теме:

  • Комментарии