^ Click Here

Tuesday, February 28, 2012

Spring Basic Example

I am providing a very basic example of Spring :-

Firstly I created a "Maven project"

Inside there is a person class person.java

package pkg;

public class Person {
    
    private String name;
    private IAnimal animal;
    
    public void setName(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }
    public IAnimal getAnimal() {
        return animal;
    }
    public void setAnimal(IAnimal animal) {
        this.animal = animal;
    }
    public String toString() {
        return name+" has a "+animal.toString();
    }
}

the Interface IAnimal.java

package pkg;

public interface IAnimal {
    public void play();
}

the animal Dog.java

package pkg;

public class Dog implements IAnimal {
    private String name;
    public void play() {
        System.out.println("Playing with "+name);
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String toString() {
        return " Dog with name "+name;
    }

}

the animal Cat.java



package pkg;

public class Cat implements IAnimal {
    private String name;
    public void play() {
        System.out.println("Playing with "+name);
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String toString() {
        return " Cat with name "+name;
    }

}

dependency management through pom file
pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.proj.blog</groupId>
  <artifactId>blogSpringTest</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <properties>
        <org.springframework.version>3.0.5.RELEASE</org.springframework.version>
    </properties>
  <dependencies>
  <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.0</version>
            <type>jar</type>
            <scope>test</scope>
            <optional>true</optional>
        </dependency>
      <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${org.springframework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${org.springframework.version}</version>
        </dependency>
  </dependencies>
</project>

configuration of spring beans
config.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:p="http://www.springframework.org/schema/p" 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.0.xsd
         http://www.springframework.org/schema/context         
         http://www.springframework.org/schema/context/spring-context-3.0.xsd">


<bean id="person" class="pkg.Person">  
    <property name="name" value="Rahul"/>
    <property name="animal" ref="Dog"/>    
</bean>
<bean id="Dog" class="pkg.Dog">
    <property name="name" value="Doug"></property>
</bean>
<bean id="Cat" class="pkg.Cat">
    <property name="name" value="Jejebel"></property>
</bean>
</beans>

Now the test class PersonTest.java

package pkg;

import org.junit.*;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class PersonTest {

    @Test
    public void animalTest(){
        ApplicationContext context = new ClassPathXmlApplicationContext("config.xml");
        Person person = (Person) context.getBean("person");
        System.out.println(person);
    }
}
The structure :-

If we run this jUnit test (PersonTest.java) the output should be - Rahul has a Dog with name Doug

Suppose if we have to make some changes to this structure for example - we want to change the animal for Person from Dog to Cat......we would simply change the ref(reference) of the property animal to Cat from Dog of the person Rahul.
So change in config.xml will be

<bean id="person" class="pkg.Person">  
    <property name="name" value="Rahul"/>
    <property name="animal" ref="Cat"/>    
</bean>

Again run the PersonTest.java jUnit test and it should provide the output as - Rahul has a Cat with name Jejebel

Change the "name" property of Cat bean

 <bean id="Cat" class="pkg.Cat">
    <property name="name" value="Petra"></property>
</bean>

run the PersonTest.java jUnit test and it should provide the output as - Rahul has a Cat with name Petra

*make a few changes and test it by yourself*

Hence we can see that we are changing the structure without touching the classes only through the xml file. So actually the control from low level is transferred to higher level this is actually known as IoC (Inversion of Control).
Also notice that just by providing the reference (ref) of Dog or Cat bean to the property animal we are able to connect two beans (person and Dog or Cat). This very feature is called Dependency Injection. Person Class is dependent on IAnimal Interface (implemented by Cat and Dog classes) and this dependency is injected by Spring Framework.

In spring framework "beans" are the most important part....beans can be understood by putting it roughly equivalent to instances which in many ways it is, However it is important to remember that it's a single(ton) instance. Spring take care of all its property and dependencies after invoking it in an application context.
Let's understand the config.xml first

 <?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:p="http://www.springframework.org/schema/p" 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.0.xsd
         http://www.springframework.org/schema/context        
         http://www.springframework.org/schema/context/spring-context-3.0.xsd">

  the above part is basically the configuration which provide us a platform to describe our beans.....as we go more in different examples it would be easier to understand this part, for now we can ignore it. 

<bean id="person" class="pkg.Person">  
    <property name="name" value="Rahul"/>
    <property name="animal" ref="Dog"/>    
</bean>
<bean id="Dog" class="pkg.Dog">
    <property name="name" value="Doug"></property>
</bean>

A bean is created with the help of pkg.Person Class definition and it's id is "person". id is actually name of bean. It consists of two properties "name" and "animal".
When we provide the value "Rahul" to the property name, actually the Spring Framework will search for "setName" method and pass the String "Rahul" to it. If the property would have been age Spring would by default search for setAge method.
Hence one should be careful that if you want to put some value to a property of a bean, you must provide a setter method(getter method isn't required) for that property. So if there is no setName the value won't be attached to property and it might throw an error.
Also for the property animal instead of value we have passed a reference (ref) to other bean with id Dog. So when the application context will be invoked it by itself connect the Dog bean to the animal property of person bean.

Note that Dog and Cat both classes implement IAnimal interface and hence both are IAnimal which is the type of animal property in Person class. Due to this fact we are able to change Dog and Cat to the animal property in config.xml file.

Understanding the jUnit test :

    ApplicationContext context = new ClassPathXmlApplicationContext("config.xml");

this actually invokes a new application context "context" of Spring Framework with the help of "config.xml". ClassPathXmlApplicationContext takes the classpath of xml file and prepares an application context from it. When this application context is created all the dependency injection is done by Spring itself.
 

    Person person = (Person) context.getBean("person");

    from the application context we get the bean "person" (note that "person" is the id of the bean in config.xml). then we typecast that bean into Person and assign it to person object.   

       System.out.println(person);

    when we try to print that person object it calls the toString() method and hence it try to print person.toString() which returns the string name(property) has a animal(property).toString(). As we have defined the property name as "Rahul" and animal as "Dog". Spring parses it into String Rahul has a Dog.toString() and eventually according to Dog class toString method it returns  "Rahul has a  Dog with name Doug".
I hope this would make it easier for you to understand the basic of Spring Framework. There are a lot more to come. Feel free to ask for clarifications and modifications.

No comments:

Post a Comment