Главная » Spring » Абстрактные компоненты Spring

0

Как рассказывалось в главе 2, Кенни был соперником тех, кто выступал в соревновании как музыкант (Instrumentalist). В частно- сти, специализацией Кенни является игра на саксофоне. Кенни был объявлен в Spring как компонент следующим образом:

<bean  id="kenny"

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

<property name="song" value="Jingle Bells" />

<property  name="instrument"  ref="saxophone"  />

</bean>

Пока вы читали главу 2, в состязания вступил новый участник. Так совпало, что Давид – тоже саксофонист. Более того, он должен играть то же самое произведение, что и Кенни. Компонент Давида объявлен в Spring следующим образом:

<bean id="david"

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

<property name="song" value="Jingle Bells" />

<property  name="instrument"  ref="saxophone"  />

</bean>

Сейчас у нас имеются два компонента, объявленные в Spring фак- тически одинаково. Как показано на рис. 3.1, единственное различие между двумя этими компонентами составляют их идентификаторы. Сейчас это может показаться небольшой проблемой, но представь- те, что может произойти, если в конкурсе будут участвовать более 50 саксофонистов, которые все как один захотят исполнить одну и ту же мелодию «Jingle Bells».

Рис. 3.1. Два компонента одного типа и с одинаковыми свойствами, имеющими одинаковые значения

Очевидным решением проблемы может быть запрет нескольким участникам участвовать в конкурсе. Но мы уже создали прецедент, разрешив выступление Давида. Кроме того, нам нужен пример соз- дания подкомпонента. Так что отложим пока открытие конкурса.

Другое решение – создать компонент, который будет родителем для всех соперничающих саксофонистов. Компонент baseSaxophonist должен будет исполнить следующий трюк:

<bean id="baseSaxophonist" class="com.springinaction.springidol.Instrumentalist" abstract="true">

<property  name="instrument"  ref="saxophone"  />

<property name="song" value="Jingle Bells" />

</bean>

На первый взгляд компонент baseSaxophonist почти не отличается от компонентов kenny и david. Но обратите внимание на его атрибут abstract со значением true. Он сообщает фреймворку Spring не пы- таться создавать экземпляр этого компонента… даже если от кон- тейнера последует явный запрос. Во многом это тот же абстрактный Java-класс, экземпляр которого не может быть создан.

Хотя экземпляр компонента baseSaxophonist нельзя создать, он все еще очень полезен, потому что содержит общие свойства, присущие Кенни и Давиду. Поэтому сейчас мы можем объявить компоненты kenny и david, как показано ниже:

<bean  id="kenny"  parent="baseSaxophonist"  />

<bean id="david" parent="baseSaxophonist" />

Атрибут parent свидетельствует, что оба компонента, kenny и david, будут наследовать определение от компонента baseSaxophonist. Об- ратите внимание на отсутствие атрибута class – компоненты kenny и david наследуют класс родительского компонента, а также его свой- ства. Мы избавились от избыточного кода XML, и элементы <bean> стали проще, как показано на рис. 3.2.

Здесь уместно упомянуть, что родительские компоненты могут быть и неабстрактными. Разумеется, вполне возможно создать под- компонент, расширяющий конкретный компонент. Но в данном примере известно, что у фреймворка Spring нет причин создавать экземпляр компонента baseSaxophonist, поэтому он был объявлен аб- страктным.

Рис. 3.2. Компоненты kenny и david

совместно используют общую конфигурацию.

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

Переопределение наследуемых свойств

Предположим, что на конкурсе появился еще один саксофонист (я говорил, что это будет происходить). Но вместо «Jingle Bells» он будет исполнять мелодию «Mary Had a Little Lamb». Означает ли это невозможность переопределения baseSaxophonist, когда будет объявляться новый участник?

Конечно нет. Мы все еще можем наследовать компонент base- Saxophonist. Но вместо того чтобы использовать значения всех насле- дуемых свойств, можно переопределить свойство song. Ниже следует объявление нового саксофониста:

<bean  id="frank"  parent="baseSaxophonist">

<property name="song" value="Mary had a little lamb" />

</bean>

Компонент frank также наследует класс и свойства компонен- та baseSaxophonist. Но, как показано на рис. 3.3, он переопределяет свойство song так, что он может исполнять песню о девочке и ее мохнатом друге.

Рис. 3.3. Компонент frank наследует baseSaxophonistbean, но переопределяет свойство song

Во многих отношениях объявления родительских и дочерних компонентов отражают возможность определения родительских и дочерних классов в Java. Но затаите дыхание… я покажу, что насле- дование в Spring может то, чего невозможно сделать в Java.

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

По теме:

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