Search This Blog

Wednesday 7 March 2012

Injecting Collections of Objects

In the previous post we saw how to inject a collection of values. However Spring is not limited to only wiring primitive values . It allows us to create collections of beans and wire them into other beans as well.
Consider the RockBand class which is made of a combination of singers, musicians, guest singers and some more.
public class RockBand implements IPerformer {
    private Collection<Singer> guestSingers;
    private List<Singer> singers = new LinkedList<Singer>();
    private Set<Musician> musicians = new HashSet<Musician>();

    private Map<String, Musician> supriseMusicians = new HashMap<String, Musician>();
    private Singer[] backgroundSingers;
//setters-getters

    @Override
    public void perform() {
        System.out.println("-----------ROCK BAND PLAYS ------------");

        for (Singer singer: this.getSingers()) {
            singer.perform();
        }
        for (Musician musician: this.getMusicians()) {
            musician.perform();
        }
        for(Singer bgSinger: this.getBackgroundSingers()) {
            bgSinger.perform();
        }
        for(Singer bgSinger: this.getGuestSingers()) {
            bgSinger.perform();
        }
        Set<String> keySet = this.getSupriseMusicians().keySet();
        for (String key : keySet) {
            Musician musician = this.getSupriseMusicians().get(key);
            System.out.println("key is " + key + " and musician " + musician);
            musician.perform();
        }
        System.out.println("-----------ROCK BAND PLAY OVER ------------");
    }
}
All the collections used work with objects and not values. The XML configuration for the above class would be as below:
<bean id="rockBand" class="com.performer.RockBand">
    <property name="musicians">
        <list>
            <ref bean="musician" />
        </list>
    </property>
    <property name="singers">
        <list>
            <ref bean="singer" />
            <ref bean="shortSinger" />
        </list>
    </property>
    <property name="guestSingers">
        <list>
            <ref bean="gSinger" />
        </list>
    </property>
    <property name="backgroundSingers">
        <list>
            <ref bean="bgSinger1" />
            <ref bean="bgSinger2" />
            <ref bean="bgSinger3" />
        </list>
    </property>
    <property name="supriseMusicians">
        <map>
            <entry key="SURPRISEOO" value-ref="musician" />
        </map>
    </property>
</bean>
For the <list> element the value child element has been replaced by a <ref> element.
Similarly for the map element, the value has been replaced with value-ref. The key in the above example is a String, a value. If the key was also a bean then the key-ref element would be used. For e.g.
private Map<Singer, Musician> pairs= new HashMap<Singer, Musician>();
The XML configuration would be:
<property name="pair">
    <map>
        <entry value-ref ="bgSinger1" value-ref="musician" />
    </map>
</property>
If we were to get the bean reference and call its perform method
public void createComplexBeans(final BeanFactory beanFactory) {
    IPerformer rockBand = (IPerformer) beanFactory.getBean("rockBand");
    System.out.println("Bean received is " + rockBand);
    rockBand.perform();
}
, the output would be as follows:
Creating new Musiscian Object com.performer.Musician@74c3aa
Creating a singer instance com.performer.Singer@196c1b0
Creating a singer instance com.performer.Singer@1292d26
Creating a singer instance com.performer.Singer@5329c5
Creating a singer instance com.performer.Singer@1db699b
Creating a singer instance com.performer.Singer@1f26605
Creating a singer instance com.performer.Singer@107ebe1
Bean received is com.performer.RockBand@544ec1
-----------ROCK BAND PLAYS ------------
singing La La La....
singing Do It....
Playing instrument Tabla...
singing Aaah aah ahh....
singing Aaah aah ahh....
singing Aaah aah ahh....
singing I am waiting....
key is SURPRISEOO and musician com.performer.Musician@74c3aa
Playing instrument Tabla...
-----------ROCK BAND PLAY OVER ------------

No comments:

Post a Comment