Using p-namespace to supply property values in Spring Configuration

Monday, May 24, 2010

In spring, property values may be supplied to the bean via the configuration information. Here is an simple example.

In this example, BasicDataSource class is initialized in the container with the values as mentioned in the property tag. Each of the property is an instance variable in the BasicDataSource class.










There is a shortcut to mention the property values. That uses p-namespace. Here is how you need to provide the values.


destroy-method="close"
p:driverClassName="com.mysql.jdbc.Driver"
p:url="jdbc:mysql://localhost:3306/mydb"
p:username="root"
p:password="masterkaoli"/>


You need to ensure that the p-namespace is included in the xml declaration else you will get following error.

Exception in thread "main" org.springframework.beans.factory.xml.XmlBeanDefinitionStoreException: Line 44 in XML document from class path resource [Configuration.xml] is invalid; nested exception is org.xml.sax.SAXParseException: The prefix "p" for attribute "p:driverClassName" associated with an element type "bean" is not bound.
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:378)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:316)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:284)
at org.springframework.beans.factory.xml.XmlBeanFactory.(XmlBeanFactory.java:73)
at org.springframework.beans.factory.xml.XmlBeanFactory.(XmlBeanFactory.java:61)
at springbeansamples.CollectionTest.main(CollectionTest.java:11)

The reason for above error is missing namespace declaration. See the typical declaration below.


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



To solve the error include the namespace declaration as mentioned in this example below. See the line number 4.


xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
...
...

Read more...

What is Dependency Injection

Thursday, May 20, 2010




Dependency Injection forms the core of Spring and it is very important to understand this concept if you want to learn Spring. I have seen many people who work on Spring but do not understand this concept thoroughly though the concept is really simple. The reason most people do not understand this is they start working on a readymade infrastructure defined for the project and make the changes in the configuration files mechanically.

However when we understand a concept it provides a great advantange because the architecture becomes clear and there are less chances and error as well as code becomes easier to debug. It also make it easier to work on code developed by other developers.

So what is Dependency Injection?
All the container managed classes in Spring are called bean. Simply stating, it means all the Beans (Classes) on which a bean depends on, is supplied by the container either via constructor argument or using the setter methods.

For example, if a Bean A is dependent on Bean B and Bean C, which may be an interface or a class, what happens is Spring container first creates the Bean A and depending on how or what configuration is mentioned, injects or in simple term, sets the appropriate dependency values in the Bean A by creating appropriate instance of Bean B. Bean A may be supplied the instances of Bean B & C either via constructor or using the setter methods on the Bean A.



How is Dependency Injection Beneficial?
Injecting the dependency at the runtime, makes it very flexible and promotes loose coupling. A class need not know about the dependency's implementation details and it becomes easier to change a dependency class without the need to change the dependent class code. This makes the application very flexible and robust.

Read more...

Spring Lookup Method Injection Example

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();

}
}

Read more...

  © Blogger template On The Road by Ourblogtemplates.com 2009

Back to TOP