11 - Injecting Collections in Spring

11.1 Overview

We often need to define a properties of type collections like map, set, list etc in our java beans. Spring provides a convenient way to inject the collections in our beans.

In this chapter we will continue our discussion on dependency injection to understand how to inject inner beans and collections like map, list etc

11.2 Injecting Collections

Spring framework provides  four type of collection ( <list>, <set>, <map> and <props>) element to configure the collections.

11.2.1 <list>

This element is used to wire a list of values and is used for List and Arrays type of objects in java. Since list and arrays allows duplicates, so the duplicates are supported in <list> tag also. This tag can be used for both simple types and beans .

List of simple types can be defined as

<bean id="country" class="Country">
     <property name="states_name">
         <list>
            <value>State 1</value>
            <value>State 2</value>
            <value>State 3</value>
            <value>State 4</value>
         </list>
      </property>
</bean>

Above tag is equivalent to

  • List<String> states_name
  • String[] states_name

Similarly list of beans can be configured using <ref> child element instead of <value> like below

<bean id="country" class="Country">
      <property name="states_name">
            <list>
                <ref bean="State1" />
                <ref bean="State2" />
                <ref bean="State3" />
                <ref bean="State4" />
            </list>
      </property>
</bean>

Above tag is equivalent to

  • List<State> states_name
  • State[] states_name

Where all 4 beans are of type custom bean “State”

11.2.2 <set>

This element is used to wire a list of values and is used for Set type  in java. Since set does allows duplicates, so the duplicates are not supported in <set> tag also. This tag can be used for both simple types and beans .

List of simple types can be defined as

<bean id="country" class="Country">
      <property name="states_name">
         <set>
            <value>State 1</value>
            <value>State 2</value>
            <value>State 3</value>
            <value>State 4</value>
         </set>
                </property>
</bean>

Above tag is equivalent to

  • Set<String> states_name

Similarly list of beans can be configured using <ref> child element instead of <value> like below

<bean id="country" class="Country">
       <property name="states_name">
           <set>
               <ref bean="State1" />
               <ref bean="State1" />
               <ref bean="State3" />
               <ref bean="State4" />
           </set>
       </property>
</bean>

Above tag is equivalent to

  • Set<State> states_name

Where all 4 beans are of type custom bean “State” .

Above state_name set will contain 3 elements as State1 bean is added twice(highlighted above) . By default all the beans are defined in a singleton scope two beans referring State1  are same and set does not allows duplicates.

11.2.3 <map>

This element is used to wire a key-value pair and  used for java.util.Map type  in java.

In Maps, key and values can be of simple types and can be of object types so <map> tag also support both simple type and beans at both key and value level.

Elements supported by <map> tag are

  • <key> - to define a key of simple type
  • <key-ref> - to define a key referring to a  bean
  • <value> - to define simple type values
  • <value-ref> - to define values referring to a bean

Map of simple types can be defined as

<bean id="country" class="Country">
       <property name="states_name">
          <map>
              <entry key="state1" value="State 1" />
              <entry key="state2" value="State 2" />
              <entry key="state3" value="State 3" />
              <entry key="state4" value="State 4" />
          </map>
       </property>
</bean>

Above tag is equivalent to

  • Map<String,String> states_name

Similarly map of beans (both key and values as beans) can be configured ike below

<bean id="country" class="Country">
       <property name="states_name">
           <map>
                <entry key-ref="state1" value-ref="State1" />
                <entry key-ref="state2" value-ref="State2" />
                <entry key-ref="state3" value-ref="State3" />
                <entry key-ref="state4" value-ref="State4” />
           </map>
       </property>
</bean>

Above tag is equivalent to

  • Map<State,State> states_name

Where all 4 beans are of type custom bean “State” .

<key> and <key-ref> can be used with both <value> and <value-ref>

11.2.4 <props> -

This element is used to define a java.util.Properties to wire a key-value pair similar to map with the only difference is that both key and value can be of type String only.

<bean id="country" class="Country">
       <property name="states_name">
            <props>
                <prop key="state1">State 1</prop>
                <prop key="state2">State 2</prop>
                <prop key="state3">State 3 </prop>
                <prop key="state4">State 4</prop>
            </props>
       </property>
</bean>

11.3 Examples

11.3.1-

 Lets write an example to use <list> and <set> tag for both simple and ref types

Solution – As any Country can have multiple states, lets write a Country   class  that contains list of States , set of States and list of states name. State class will have state name and code

  1. Write a State Class as below
public class State {
       private String name;
       private String countryCode;
       public String getName() {
              return name;
       }
       public void setName(String name) {
              this.name = name;
       }
       public String getCountryCode() {
              return countryCode;
       }
       public void setCountryCode(String countryCode) {
              this.countryCode = countryCode;
       }
       @Override
       public String toString() {
              return "State [name=" + name + ", countryCode=" + countryCode + "]";
       }
}

b. Write a Country class as below

import java.util.List;
import java.util.Set;
public class Country {
       private List<String> statesName ;
       private List<State> statesList ;
       private Set<State> statesSet ;
       public List<String> getStatesName() {
             return statesName;
       }
       public void setStatesName(List<String> statesName) {
              this.statesName = statesName;
       }
       public List<State> getStatesList() {
              return statesList;
       }
       public void setStatesList(List<State> statesList) {
              this.statesList = statesList;
       }
       public Set<State> getStatesSet() {
              return statesSet;
       }
       public void setStatesSet(Set<State> statesSet) {
              this.statesSet = statesSet;
       }
}

c. Define beans.xml with below beans configurations.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
       <bean id="State1" class="State">
              <property name="name" value="United States" />
              <property name="countryCode" value="+1" />
       </bean>
       <bean id="State2" class="State">
              <property name="name" value="United Kingdom" />
              <property name="countryCode" value="+44" />
       </bean>
       <bean id="State3" class="State">
              <property name="name" value="India" />
            <property name="countryCode" value="+91" />
       </bean>
       <bean id="country" class="Country">
              <property name="statesName">
                     <list>
                           <value>United States</value>
                           <value>United Kingdom</value>
                           <value>India</value>
                     </list>
              </property>
              <property name="statesList">
                     <list>
                           <ref bean="State1" />
                           <ref bean="State1" />
                           <ref bean="State2" />
                           <ref bean="State3" />
                     </list>
              </property>         
              <property name="statesSet">
                     <set>
                           <ref bean="State1" />
                           <ref bean="State1" />
                           <ref bean="State2" />
                           <ref bean="State3" />
                     </set>
              </property>
        </bean>
</beans>
  1. Write a TestCollection to test the program
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestCollection {
       public static void main(String[] args) {
              ApplicationContext context =
                           new ClassPathXmlApplicationContext("beans.xml");
              Country country = (Country)context.getBean("country"); 
              System.out.println(country.getStatesName());             
              System.out.println(country.getStatesList());             
              System.out.println(country.getStatesSet());             
       }
}
  1. Run the program – You will see below output. We can see there are four states in states list but three states in states set displayed because beans are singleton and  set does not support duplicates

11.3.2  Lets write an example to use <map> tag

Solution – As any Bank can have multiple accounts , lets write a Bank  class  that contains map of Accounts. Account number will be used as a key and Account object as a value. Account class will have account holder name and balance in account. Also bank will have a map of String to store the weekly timings . Key of this timings map will be a day name and value will be the timings.

  1. Write a Account Class as below
public class Account {
       private String holderName ;
       private String balance ;
       public String getHolderName() {
              return holderName;
       }
       public void setHolderName(String holderName) {
              this.holderName = holderName;
       }
       public String getBalance() {
              return balance;
       }
       public void setBalance(String balance) {
              this.balance = balance;
       }
       @Override
       public String toString() {
       return "Account [holderName=" + holderName + ", balance=" + balance + "]";
       }
}
  1. Write a Bank class as below
import java.util.Map;
public class Bank {      
       private String name;      
       private Map<String,Account> accounts      
       private Map<String,String> timings ;
       public String getName() {
              return name;
       }
       public void setName(String name) {
              this.name = name;
       }
       public Map<String, Account> getAccounts() {
              return accounts;
       }
       public void setAccounts(Map<String, Account> accounts) {
              this.accounts = accounts;
       }
       public Map<String, String> getTimings() {
              return timings;
       }
       public void setTimings(Map<String, String> timings) {
              this.timings = timings;
       }      
}
  1. Define beans.xml with below beans configurations.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
       <bean id="Account1" class="Account">
              <property name="holderName" value="Joe"></property>
              <property name="balance" value="$1200"></property>
       </bean>
       <bean id="Account2" class="Account">
              <property name="holderName" value="Bloggs"></property>
              <property name="balance" value="$2200"></property>
       </bean>      
       <bean id="Account3" class="Account">
              <property name="holderName" value="Gary"></property>
              <property name="balance" value="$1800"></property>
       </bean>
       <bean id="bank" class="Bank">
              <property name="name" value="My Bank Name"/>             
              <property name="timings">
              <map>
                     <entry key="Monday" value="8:00 AM to 5:00 PM"/>
                     <entry key="Tuesday" value="8:00 AM to 5:00 PM"/>
                     <entry key="Wednesday" value="9:00 AM to 6:00 PM"/>
                     <entry key="Thursday" value="9:00 AM to 5:00 PM"/>
                     <entry key="Friday" value="9:00 AM to 5:00 PM"/>
                     <entry key="Saturday" value="9:00 AM to 1:00 PM"/>
                     <entry key="Sunday" value="Holiday"/>                    
              </map>       
              </property>             
              <property name="accounts">
                     <map>
                           <entry key="account1" value-ref="Account1"/>
                           <entry key="account2" value-ref="Account2"/>
                           <entry key="account3" value-ref="Account3"/>                          
                     </map>       
              </property>             
       </bean>
</beans>
  1. Write a TestMapCollection to test the program
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestMapCollection {
       public static void main(String[] args) {
              ApplicationContext context =
                           new ClassPathXmlApplicationContext("beans.xml");
              Bank bank = (Bank)context.getBean("bank");             
              System.out.println("Bank Name :" + bank.getName());
              System.out.println("Bank Timings :" + bank.getTimings());
              System.out.println("Bank Accounts :" + bank.getAccounts());
       }
}
  1. Run the program – You will see below output.

11.3.3  Write an example to use <props> tag

Solution –  Properties are key value pair with both are type String. Lets write a DataSource class which will have a properties object to contain database properties.

f. Write a DataSource Class as below

import java.util.Properties;
public class DataSource {      
       private Properties dbProperties;
       public Properties getDbProperties() {
              return dbProperties;
       }
       public void setDbProperties(Properties dbProperties) {
              this.dbProperties = dbProperties;
       }      
}
  1. Define beans.xml with below beans configurations.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
       <bean id="datasource" class="DataSource">             
              <property name="dbProperties">
                     <props>
                           <prop key="username">root</prop>
                           <prop key="password"></prop>
                           <prop key="host">localhost</prop>
                           <prop key="port">3306</prop>
                     </props>            
              </property>
        </bean>
</beans>
  1. Write a TestPropsCollection to test the program
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
       <bean id="datasource" class="DataSource">             
              <property name="dbProperties">
                     <props>
                           <prop key="username">root</prop>
                           <prop key="password"></prop>
                           <prop key="host">localhost</prop>
                           <prop key="port">3306</prop>
                     </props>            
              </property>
        </bean>
</beans>
  1. Run the program – You will see below output.

Like us on Facebook