Spring has its own advantages and disadvantages. The complete details of these can be found in many other web sites. Here I will list on the examples which would be of help for the people who would like to run and see the application. The theory behind the concepts can be found in the spring's official website.
Remember, in Spring the power is
Java reflection. So some where or the other there is tight coupling. Spring uses reflection and manages the life cycle of the object. These objects are created when the server starts and before it is ready to server the request(provided context is used to load the beans). This means there is much start up time and good response time since the objects are already created. The examples here can be made without the interface as well. The examples are written on the spring-framework-2.0.8.
There are two basic DI in Spring. The
constructor and the
setter. In the constructor injection the property of the class is set/injected using the parametrised constructor. In the setter injection the property of the class is set/injected using the setter method of the class.
Let the interface be
package test.spring.injection; public interface LoginService{ public boolean login(String userName, String password); } |
The concrete class be
package test.spring.injection; public class LoginServiceImpl implements LoginService { public boolean login(String userName, String password) { // Some logic here to login in the user. boolean success = false; if(userName != null && password != null){ success = true; } return success; } } |
The client/class using the service
package test.spring.injection; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.xml.XmlBeanFactory; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.core.io.FileSystemResource; import org.springframework.core.io.Resource;
public class ThirdPartyUsingService { private String userName = null; private String password = null; private LoginService loginService = null;
public ThirdPartyUsingService(){}
public ThirdPartyUsingService(String userName, String password){ this.userName = userName; this.password = password; }
public ThirdPartyUsingService(String userName, String password, LoginService loginService){ this.userName = userName; this.password = password; this.loginService = loginService; }
public boolean helpLogin(String userName, String password){ return loginService.login(userName, password); }
public LoginService getLoginService() { return loginService; }
public void setLoginService(LoginService loginService) { this.loginService = loginService; }
public String getPassword() { return password; }
public void setPassword(String password) { this.password = password; }
public String getUserName() { return userName; }
public void setUserName(String userName) { this.userName = userName; }
public static void main(String arg[])throws Exception { // This uses the constructor with three parameters to inject the dependency. Resource xmlResource = new FileSystemResource("bin//test//spring//injection//injection.xml"); BeanFactory factory = new XmlBeanFactory(xmlResource); ThirdPartyUsingService tpService = (ThirdPartyUsingService) factory.getBean ("thirdPartyUsingService"); boolean whatHappened = tpService.helpLogin(tpService.getUserName(), tpService.getPassword()); System.out.println("What happened to Login? :"+whatHappened);
// This uses the 2 parameter constructor to inject the two strings and setter injection to inject the service. Resource xmlResource_1 = new FileSystemResource("bin//test//spring//injection//injection-1.xml"); BeanFactory factory_1 = new XmlBeanFactory(xmlResource_1); ThirdPartyUsingService tpService_1 = (ThirdPartyUsingService) factory_1.getBean("thirdPartyUsingService"); boolean whatHappened_1 = tpService_1.helpLogin(tpService_1.getUserName(), tpService_1.getPassword()); System.out.println("What happened to Login? :"+whatHappened_1);
// This uses the default constructor and setter injection to set all the properties. ApplicationContext ctx = new ClassPathXmlApplicationContext("test//spring//injection//injection-2.xml"); ThirdPartyUsingService tpService_2 =(ThirdPartyUsingService) ctx.getBean("thirdPartyUsingService"); boolean whatHappened_2 = tpService_2.helpLogin(tpService_2.getUserName(), tpService_2.getPassword()); System.out.println("What happened to Login? :"+whatHappened_2);
// This uses the default constructor to set all the properties using the autowire=autodetect. ApplicationContext ctx_1 = new ClassPathXmlApplicationContext("test//spring//injection//injection-3.xml"); ThirdPartyUsingService tpService_3 =(ThirdPartyUsingService) ctx_1.getBean("thirdPartyUsingService"); boolean whatHappened_3 = tpService_3.helpLogin(tpService_3.getUserName(), tpService_3.getPassword()); System.out.println("What happened to Login? :"+whatHappened_3);
// Load the bunch of bean defs. String[] configFiles = new String[] { "test//spring//injection//injection.xml", "test//spring//injection//injection-1.xml" , "test//spring//injection//injection-2.xml" , "test//spring//injection//injection-3.xml" }; ApplicationContext ctx_2 = new ClassPathXmlApplicationContext(configFiles); ThirdPartyUsingService tpService_4 =(ThirdPartyUsingService) ctx_2.getBean("thirdPartyUsingService"); boolean whatHappened_4 = tpService_4.helpLogin(tpService_4.getUserName(), tpService_4.getPassword()); System.out.println("What happened to Login? :"+whatHappened_4); } }
| |
injection.xml
<beans> <bean id="loginServiceImpl" class="test.spring.injection.LoginServiceImpl" /> <bean id="thirdPartyUsingService" class="test.spring.injection.ThirdPartyUsingService"> <constructor-arg index="0" type="java.lang.String" value="Login user name."/> <constructor-arg index="1" type="java.lang.String" value="password of the user."/> <constructor-arg index="2"> <ref bean="loginServiceImpl"/> </constructor-arg> </bean> </beans>
|
injection-1.xml
<beans> <bean id="loginServiceImpl" class="test.spring.injection.LoginServiceImpl" /> <bean id="thirdPartyUsingService" class="test.spring.injection.ThirdPartyUsingService"> <constructor-arg index="0" type="java.lang.String" value="Login user name."/> <constructor-arg index="1" type="java.lang.String" value="password of the user."/> <property name="loginService"> <ref bean="loginServiceImpl"/> </property> </bean> </beans>
|
injection-2.xml
<beans> <bean id="loginServiceImpl" class="test.spring.injection.LoginServiceImpl" /> <bean id="thirdPartyUsingService" class="test.spring.injection.ThirdPartyUsingService"> <property name="userName"> <value>User Name.</value> </property> <property name="password"> <null/> </property> <property name="loginService"> <ref bean="loginServiceImpl"/> </property> </bean> </beans>
|
injection-3.xml
<!-- Setting the default autowire to byName --> <beans default-autowire="byName"> <bean id="loginServiceImpl" class="test.spring.injection.LoginServiceImpl" /> <!-- The parameter for the autowire can be changed to byName, byType or constructor, overriding tht default--> <bean id="thirdPartyUsingService" class="test.spring.injection.ThirdPartyUsingService" autowire="autodetect"> <!-- Notice the parameters are not in the order of String, String, Object --> <constructor-arg value="Login user name."/> <constructor-arg> <ref bean="loginServiceImpl"/> </constructor-arg> <constructor-arg value="password of the user."/> </bean> </beans>
|
When the injection.xml file is loaded the bean (Object thirdPartyUsingService) is created using the three parameterised constructor. i.e. the properties are injected through the constructor. Notice the index of the parameter and the type are also provided. The injection-1.xml is similar just that the index and type are not mentioned (default autowire).
When the injection-2.xml is loaded the bean is created with the default constructor and then the setter methods are used to set/inject the property of the class.
In injection-3.xml the default behaviour is provided and then this is overridden by the beans specific type of overloading
We can also inject the inner class as well. This injected inner class life cycle is determined by the outer class.
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd"> <!-- Setting the default autowire to byName --> <beans default-autowire="byName"> <!-- The parameter for the autowire can be changed to byName, byType or constructor, overriding tht default--> <bean id="thirdPartyUsingService" class="test.spring.injection.ThirdPartyUsingService" autowire="autodetect"> <!-- Notice the parameters are not in the order of String, String, Object --> <constructor-arg value="Login user name."/> <constructor-arg> <bean class="test.spring.injection.LoginServiceImpl" /> </constructor-arg> <constructor-arg value="password of the user."/> </bean> </beans>
|
NOTE: The beans are singlton by default and are replaced when it is loaded from the other def xml file.