Core Spring : Inner Beans, Alias, Injecing List and Autowiring

In our previous tutorial, we saw how to inject values for the field using property tag, constructor-arg and injecting other object using spring.xml. For injecting other object, we created beans for it and then reference it to the bean wher we want to inject, for example homeAddress, officeAddress. This was these beans are available to all other beans. Now homeAddress for each Employee will be private to that bean and it makes no sense to have it in open referrable to other bean. So, it should be an inner bean rather than a normal bean. Changing spring.xml:


<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
 xsi:schemaLocation="http://www.springframework.org/schema/beans
 http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
 http://www.springframework.org/schema/context
 http://www.springframework.org/schema/context/spring-context-3.2.xsd">

 

<bean id="employee" class="mynotes.corespring.test.Employee">
 <constructor-arg value="John" type="String"></constructor-arg>
 <constructor-arg value="20" type="int"></constructor-arg>
 <property name="homeAddress">
 <bean class="mynotes.corespring.test.Address">
 <property name="street" value="Street1"></property>
 <property name="city" value="City1"></property>
 <property name="pincode" value="123456"></property>
 </bean>
 </property>
 <property name="officeAddress" ref="officeAddress"></property>
 </bean>

<bean id="officeAddress" class="mynotes.corespring.test.Address">
 <property name="street" value="Street2"></property>
 <property name="city" value="City2"></property>
 <property name="pincode" value="654321"></property>
 </bean>

</beans>

Run and check. As you can see the inner bean is inside the property tag. The id tag is also not required because you cannot refer it now from any other bean.

There is one another naming convention that the spring provides, its called aliases. By using it ou can give different names to the same bean and then refer it using these aliases. For this we have to use an aliases tag. You can also define it in the bean definition tag with attribute ‘name’. Lets see this with the officeAddress bean:


<bean id="employee" class="mynotes.corespring.test.Employee">
 <constructor-arg value="John" type="String"></constructor-arg>
 <constructor-arg value="20" type="int"></constructor-arg>
 <property name="homeAddress">
 <bean class="mynotes.corespring.test.Address">
 <property name="street" value="Street1"></property>
 <property name="city" value="City1"></property>
 <property name="pincode" value="123456"></property>
 </bean>
 </property>
 <property name="officeAddress" ref="officeAddress-alias"></property>
 </bean>

<bean id="officeAddress" class="mynotes.corespring.test.Address" name="officeAddress-name">
 <property name="street" value="Street2"></property>
 <property name="city" value="City2"></property>
 <property name="pincode" value="654321"></property>
 </bean>
 <alias name="officeAddress" alias="officeAddress-alias"/>

Now as you can see, we can refer ‘officeAddress‘ bean using ‘ officeAddress-alias’ defined in alias tag and ‘officeAddress-name’ defined in officeAddress bean itself. Its always better to use id tag instead of using these. To make sure of that you can use idref  instead.

Lets add another varialbe to our Employee class – a list of programmingLanguage . Change toString accordingly


private List<String> programmingLaguages;

//getter and setters for this

//other properties and there getter and setters

@Override
 public String toString() {
 String allLanguages = null;

 for (String language : this.programmingLaguages) {
 if(allLanguages==null){
 allLanguages=language+";";
 }else{
 allLanguages=allLanguages+language+";";
 }
 }

 return ("Id=>" + this.id + " Name=>" + this.name + "\nhomeAddress=>"
 + this.homeAddress + "\nofficeAddress=>" + this.officeAddress
 + " \nAllLanguage=>"+allLanguages);
 }

To initialised this list in spring.xml :


<property name="programmingLaguages">
 <list>
 <value>Java</value>
 <value>PL/SQL</value>
 <value>JavaScript</value>
 </list>
 </property>

The above is to be added inside the “employee” bean. Note that there is type conversion which is automatically be done by spring. If you have a list of a particular class. then instead of value tag you will be using <ref> tag which refer to the other bean. again the type conversin is automatically done by spring. Running App.java


Id=>20 Name=>John
homeAddress=>street::Street1 city::City1 pincode::123456
officeAddress=>street::Street2 city::City2 pincode::654321
AllLanguage=>Java;PL/SQL;JavaScript;

Autowire helps us in reducing some of the configuration that we need to do in spring.xml. Lets autowire our employee bean byName, and delete the property tag for ‘officeAddress’ .

<bean id="employee" class="mynotes.corespring.test.Employee" autowire="byName">
<constructor-arg value="John" type="String"></constructor-arg>
<constructor-arg value="20" type="int"></constructor-arg>
<property name="homeAddress">
<bean class="mynotes.corespring.test.Address">
<property name="street" value="Street1"></property>
<property name="city" value="City1"></property>
<property name="pincode" value="123456"></property>
</bean>
</property>
<property name="programmingLaguages">
<list>
<value>Java</value>
<value>PL/SQL</value>
<value>JavaScript</value>
</list>
</property>
</bean>

<bean id="officeAddress" class="mynotes.corespring.test.Address" name="officeAddress-name">
<property name="street" value="Street2"></property>
<property name="city" value="City2"></property>
<property name="pincode" value="654321"></property>
</bean>

Notice the autowire=”byName” in the employee bean and absence of any officeAddress property tag. Now, since the autowire is enable, spring will first initialise all the attributes values of the Employee class given inside the employee bean. If its not able to find few values like officeAddress in our case, it will search with that name of the attribute (officeAddress) in spring.xml to check if there exsist a bean with that name. If yes, it will assign that to this. Running app.java with this we will get the same result.

autowire=”constructor”  does the same thing but instead of doing a setter injection , it do a constructor injection i.e will inject only those that are setted in constructor.  Similar for other cases. Autowire is OK for small projects but for big ones it might create problems to know what is getting injected where.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: