Spring Lookup Method Injection Example

Thursday, May 20, 2010

Just imagine a situation where in you have a Singleton Bean A (In Spring Singleton means exactly one bean per container) and that bean is dependent on another bean B which you do not want to be singleton (Prototype - Multiple copies of the bean can exist for the bean in the container).

In case of Singleton beans, it is initialized only once therefore the dependency bean is also initialized only once though the scope may be Prototype. To solve the problem Spring provides a solution where in the look-up for the dependency bean B is done dynamically and each time container would return a new instance of bean B.

In this example I will first show what happens when we do not use the look up feature and then we have a look at what happens when we use the look-up feature.

Scenario is like this:
We have a Physiotherapist class which can enroll Patients. Imagine that we can only have a single Physiotherapist he can have multiple patients, therefore we have limited the scope of Physiotherapist to singleton. Patient class has Prototype scope which means that it can have multiple instances.

When we do not use the method lookup injection the Patient instance which is initially injected to the singleton class stays and new instance of Patient class is not created since this dependency injection takes place only once during the creation of Physiotherapist class.

Here is the Patient Class. We assign a patient number randomly and that will be used to verify if the instance of the patient class is same or different.


package springbeansamples;

/**
* @author nilendu.bhattacharya
*
*/
public class Patient {
String patientNumber=Integer.toString((int) (Math.random()*100000));
/**
* @return Returns the type.
*/
public String getPatientNumber() {
return patientNumber;
}


}


Here is the Physiotherapist Class.

package springbeansamples;

/**
* @author nilendu.bhattacharya
*/
public class Physiotherapist {
Patient patient;
/**
* @return Returns the patient.
*/
public Patient getPatient() {
return patient;
}
/**
* @param patient The patient to set.
*/
public void setPatient(Patient patient) {
this.patient = patient;
}

public void showPatientDetails(){
Patient patient = enrolPatient();
// Show the patient number of (hopefully brand new) new Patient instance
System.out.println("New Patient Number is : "+patient.getPatientNumber());
}

public Patient enrolPatient(){
return getPatient();
}
}



This is the entry in the configuration file for the beans.













This the result. Notice that same patient instance is there the Physiotherapist instance.


May 21, 2010 3:50:56 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [SpringTest.xml]
New Patient Number is : 34271
New Patient Number is : 34271


Here is the changed Physiotherapist class.

package springbeansamples;

/**
* @author nilendu.bhattacharya
*/
public abstract class Physiotherapist {
Patient patient;
/**
* @return Returns the patient.
*/
public Patient getPatient() {
return patient;
}
/**
* @param patient The patient to set.
*/
public void setPatient(Patient patient) {
this.patient = patient;
}

public void showPatientDetails(){
Patient patient = enrolPatient();
// Show the patient number of (hopefully brand new) new Patient instance
System.out.println("New Patient Number is : "+patient.getPatientNumber());
}

//This is where the lookup injection will take place. This is abstract method.
public abstract Patient enrolPatient();
}




Bean configuration in the Spring configuration file for method lookup injection. Notice that in the bean physiotherapist we have reference to lookup-method














Here is the output which show how New instance of Patient is generated.


May 21, 2010 3:54:34 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [SpringTest.xml]
New Patient Number is : 51362
New Patient Number is : 3906



Below is the MethodInjectionTest code. Use this class to test if new instance is created for the Patient class.


package springbeansamples;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;

/**
* @author nilendu.bhattacharya
*
*/
public class MethodInjectionTest {
public static void main(String[] args) {
XmlBeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("SpringTest.xml"));

Physiotherapist physiotherapist = (Physiotherapist) beanFactory.getBean("physiotherapist");
physiotherapist.showPatientDetails();
physiotherapist = (Physiotherapist) beanFactory.getBean("physiotherapist");
physiotherapist.showPatientDetails();

}
}

2 comments:

Pepperwick.in June 3, 2010 at 4:08 AM  

In Spring framework, we define our services bean in the spring-config.xml file and not our entities.

In your example, Patient is an entity and not a service so we should not specify Patient in .xml file.

AWS Notes June 8, 2010 at 2:21 AM  

Hi Yatendra,

Thanks a lot for pointing this out and I really appreciate your comment.

Ideally speaking each entity should be defined separately especially when related to persistence layer. In this example I am trying to show Lookup Method injection in a simple manner and with a java based application instead of enterprise of web base application. For simplicity sake sometimes few things need to be sacrificed so that the example is based on the point being discussed.

Since this is a new blog I would welcome suggestions from all of you which can help others.

Regards,
Nilendu Bhattacharya

Post a Comment

  © Blogger template On The Road by Ourblogtemplates.com 2009

Back to TOP