Spring - Dependency Injection
The dependency injection is about building relationships of the objects. The dependencies can be of primitive types or other objects. Spring support two types of dependency injection:- Constructor Dependency Injection: The dependency is injected via constructor arguments.
- Setter Dependency Injection: Dependency is provided through setter methods as per Java Bean style.
Constructor Dependency Injection
Let's have a constructor in User which has arguments
User.java
public class User { User(String first,String last){ firstName =first; lastName = last; } }
Now to inject the dependencies, put the dependencies via configuration XML
<bean id=“user” class=“User”> <constructor-arg value=“ChandraGupta"/> <constructor-arg value=“Maurya"/> </bean>
The argument resolution is done by doing type matching.The matching is done in the order it is defined. For better ambiguity resolution we can use type or index.
Suppose we have a constructor User(int,double) than we can use
<bean id=“user” class=“User”> <constructor-arg type="int" value="45" /> <constructor-arg type="double" value="58.5" /> </bean>
or
<bean id=“user” class=“User”> <constructor-arg index= "0" value="45" /> <constructor-arg index= "1" value="58.5" /> </bean>
If suppose we have two constructors User(String) and User(int) and have the following in XML
<bean id=“user” class=“User”> <constructor-arg value="45" /> </bean>
Spring will go for User(String), as there is no way for it figure out that the value is a number. In XML everything is String. However if you want to use User(int) than qualify it with type.
Setter Dependency Injection
In setter based dependency injection, the bean style setter are used by Spring to set the properties. In our example of User, the properties can be set by injecting properties
<bean id=“user” class=“User”> <property name=“firstName" value="ChandraGupta"/> <property name=“lastName" value="Maurya"/> </bean>
Constructor vs Setter Dependency Injection
Which is better? Constructor based dependency injection forces to set the property. However the property cannot be changed later on. Setter based dependency injection allows reconfiguration later on. You have have both Constructor based dependency injection and Setter based dependency injection also together.
Dependency Injection
Spring supports various kind of dependency injection which includes:
- Primitive type and Simple Values(like String): The above example belong to this category.
- Other beans in same or parent factory: We can provide other beans also as dependency. Multiple Spring factories can be built with parent child relationships. In that case we can inject bean from parent factory to child factory.
- Collections: We can inject Properties,Set,List and Map.
- Properties defined in external properties/resource files: This is useful for properties which change at deployment levels.
Primitive type and Simple Values
Suppose User has three properties age,height and firstName and corresponding setters than we can inject those properties through configuration XML
<bean id=“user" class=“User"> <property name="age" value="64" /> <property name="height" value="184.20" /> <property name=“firstName" value="Amitabh" /> </bean>
Other beans in same or parent factory
Let's write an Address class and we will inject some addresses in our User class
Address.java
public class Address { private String street; private String city; //Setters and getters for street and city ... }
Let's introduce two address reference in User.java
User.java
Address homeAddress; Address officeAddress; //Setters and getters for the address properties
Now Let's have two Address bean in Spring and we inject them in User
<bean id= “officeAdd" class=“Address"> <property name="street" value="dadar"/> <property name="city" value="Mumbai"/> </bean> <bean id= “homeAdd" class="Address"> <property name="street" value="dadar"/> <property name="city" value="Mumbai"/> </bean> <bean id="user" class="User"> <property name="officeAddress"> <ref bean= “officeAdd" /> </property> <property name=" homeAddress "> <ref bean= “homeAdd " /> </property>
ref allows creating a reference to any bean in the same or parent container. Also we can inject bean of any type or subtype. Spring honors the inheritance hierarchy. If we want to restrict the wiring to the local container only, than configuration will be:
<bean id="user" class="User"> <property name="officeAddress"> <ref local = "address" /> </property>
Similarly for referencing the bean only in parent container
<bean id="user" class="User"> <property name="officeAddress"> <ref parent = "address" /> </property>
You can also inject beans as inner beans. Inner beans are similar to inner classes.They are anonymous and always scoped as prototype. The name and id is not defined for inner bean. Even if they are defined it is ignored.Also it is not possible to inject inner beans into other beans.
<bean id="user" class="User"> <property name="officeAddress"> <bean class="Address"> <property name="street" value="dadar" /> <property name="city" value="Mumbai" /> </bean> </property> </bean>
Injecting Collections
In Spring you can inject collection of type Properties, List, Map and Set
Properties injection: Let's have a java.util.Properties phoneNumbers in User and have setters and getters for it.
<!-- results in a setPhoneNmubers(java.util.Properties) call --> <property name=“phoneNumbers"> <props> <prop key=“personal">1234</prop> <prop key=“official">5678</prop> <prop key=“secret">8888</prop> </props> </property>
Similarly for List have the properties and inject it through XML
<!-- results in a setRecoveries(java.util.List) call --> <property name="recoveries"> <list> <value>"House Rent"</value> <value>"Over Payment"</value> <value>"House Rent"</value> </list> </property>
For Set
<property name="loans"> <set> <value>"Monthly Premium"</value> <value>"Education"</value> <value>"Monthly Premium"</value> </set> </property>
For Maps
<property name="emails"> <map> <entry> <key><value>"personal"</value></key> <value>aa@gmail.com</value> </entry> <entry> <key><value>"official"</value></key> <value>bb@crayom.com</value> </entry> </map> </property>
Spring supports merging of collections also.
<bean id="parent" abstract="true" class=“User"> <property name="phoneNumbers"> <props> <prop key="personal">1111</prop> <prop key=“office">2222</prop> </props> </property> </bean> <bean id="child" parent="parent“ class=“User”> <property name="phoneNumbers"> <!-- the attribute merge="true" tells it to take the properties from Parent and than append it from here --> <props merge="true"> <prop key="office">5555</prop> <prop key="secret">8888</prop> </props> </property> </bean>
With Java5+ Generics feature we can have type safe collections. Suppose user has a Map defined as
private Map<String,Float>marks;
In spring configuration
<property name=“marks"> <map> <entry> <key><value>"maths"</value></key> <value>56</value> </entry> <entry> <key><value>"Physics"</value></key> <value>77</value> </entry> </map> </property>
Without type safety from Generics, the collection contains plain String objects.
Shortcuts for injecting Dependencies
you can use shortcuts to inject dependencies. Prefer them than the verbose way of writing the things
<property name="age" value="32"/> <constructor-arg value="Chandragupta"/> <entry key="maths" value="56"/> <property name="officeAddress" ref="officeAdd"/> <constructor-arg ref="homeAdd"/>
Compound Property injection
Spring can deep dive into the relationships and can set the values.
<bean id=“user” class=“User”> <property name= “homeAddress.city" value="Pune"/> </bean>
This will result in call of getHomeAddress().setCity("Pune"). Be careful that now you are responsible for instantiating honeAddress reference properly before Spring reaches to set this property. The nesting can be any level deep.
Lazy initialization
By default Spring creates the singleton beans eagerly. The prototype beans are created on demand only. However if you want to change the behaviour so that singleton beans are also created on demand than use lazy-init attribute
<bean id=“user" class="User" lazy-init="true"/>
Lazy initialization can be turned on at container level
Spring Framework Index Java Home Home
Sidebar
Last wiki comments
- Introduction to ORM: ugg boots
- Introduction to ORM: ugg boots
- AOP: Thanks
- Lalit Bhatt: Superb Collection
- Lalit Bhatt: J2EE training
- Introduction to ORM: timberland shoes
- Introduction to ORM: jordan shoes
- Introduction to ORM: nike air max
- Pune Tourist Spots: KONARK PARK CLOSED
- jQuery Form Validations: Jquery Developer
Sidebar
Random Pages
- What markets work on?
- Why projects fail?
- Bharat Band - Jai ho
- The concept of Nation
- Don't hide complexity if it cannot be handled in a robustway
Last blog post comments
-
Prospective MLA for Pune election - 2009: ugg boots
Wed 01 of Sep., 2010 12:58 IST
-
Bharat Band - Jai ho: How do we protest?
Wed 18 of Aug., 2010 13:13 IST
-
Divided by Destiny: Contact
Fri 23 of July, 2010 16:02 IST
-
Future of Java: thesis writing
Sat 17 of July, 2010 01:50 IST
-
Hang till Death Mr. Kasab: some change
Mon 28 of June, 2010 16:03 IST
-
God Religion : Why we are confused?: Re: Is GOD Necessary?
Tue 15 of June, 2010 17:29 IST
-
God Religion : Why we are confused?: Is GOD Necessary?
Tue 15 of June, 2010 13:06 IST
-
The reason in religion: good
Wed 10 of Mar., 2010 18:30 IST
-
The confusion of Design Patterns: I think at macro level you are right...
Tue 23 of Feb., 2010 03:31 IST
-
The Indian Municipality: Comment
Fri 22 of Jan., 2010 13:20 IST
Post new comment