Setup and Teardown

We all know the functionality of the init() method in the servlet. We also agree this is one of the best or a fantastic API of the servlet lifecycle. Spring provides the similar configurable support for the BEAN, but note this is not the callback API nor has a mandatory naming (reserve word). This also has a lot of difference in the servlet's init() and this configurable custom initilization method. I generally compare these two since I personaly feel they are similar and it help most of them.

Now lets come to the Spring, after the constructor is used to create the object of the class, we can configure a method to be called by the spring container (init() is called by the servlet container). After the constructor is done with its defined job and we need some other peice of code to invoked which might be used once in the life cycle of the object, we can configure this method as the init-method for this bean.

I found this very useful when we had a different encryption and decription keys for the objects and is independent to the intentions of the bean creation. So I configure this init-method and destroy-method to achieve this. Here is the typical code for the same.






package test.spring.injection;

public class CustomInit {
  
  public CustomInit(){
    System.out.println("This is the default constructor...");
  }
  
  public void setEncryptionKey(){
    System.out.println("Go to DB/Context load the key");
  }
  
  public void broadcastEncryptionKey(){
    System.out.println("Shout you are erased...");
  }

}






<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans>
<beans>
  <bean id="customInit" class="test.spring.injection.CustomInit"
    init-method="setEncryptionKey"
    destroy-method="broadcastEncryptionKey" />
</beans>


The best approach then the above would be to implement the InitializingBean and DisposableBean. Now override the afterPropertiesSet() [implement init-method logic here] and destroy() [implement the destroy-method logic here]. These are the bean lifecycle API's

Spring DI (factory method)

Now that we understand the Spring Dependency Injection and the singleton implementation, and we also know how to configured the class as bean in spring definition file which has the constructor either the default or overridden. Let’s understand how to configure the singleton class in spring.
To highlight the scenario singleton does not have a public constructor (which means new keyword cannot be used to instantiate the object of this class) and has a public static getInstance method to get the instance of the class.
Spring provided the way to configure such classes as beans through the factory methods. Here we will configure the factory-method which is responsible to return the object of the class.

The singleton class would be


The singleton I read in the "Spring in Action" book
package test.patterns;

public class SingltonInner {

  private SingltonInner(){}
  
  private static class InnerSingltonInstance{
    static SingltonInner singlton = new SingltonInner();
  }
  
  public static SingltonInner getInstance(){
    return InnerSingltonInstance.singlton;
  }
  
  public String getMessage(String name){
    return "Hello " + name;
  }
}

Java2html

The class using the Singleton

package test.spring.injection;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import test.patterns.SingltonInner;

public class FactoryInjection {
  
  private SingltonInner singleton = null;
  
  public SingltonInner getSingleton() {
    return singleton;
  }

  public void setSingleton(SingltonInner singleton) {
    this.singleton = singleton;
  }
public public static void main(String arg[]){
        ApplicationContext ctx_1 = new ClassPathXmlApplicationContext("test//spring//injection//factory-injection.xml");
        FactoryInjection fInjection =(FactoryInjectionctx_1.getBean("factoryInjection");    
        System.out.println("Calling the singleton method :"+fInjection.singleton.getMessage("Java Om"));    
  }
}
Java2html


The definition of the beans is in this XML file.


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans>
    <bean id="factoryInjection" class="test.spring.injection.FactoryInjection">
        <property name="singleton">
            <ref bean="singltonInner"/>
        </property>
    </bean>
    <bean id="singltonInner" class="test.patterns.SingltonInner" factory-method="getInstance"/>
</beans>

Singlton

While writing the Singleton class I would consider these things


  • Make the default constructor private.
  • Create a static and public getInstance method returning the object of the singleton class.
  • Make the class final.
  • Implement the Cloneable interface.
  • Override the clone method to throw the CloneNotSupportedException.

package test.patterns;
public final class Singlton implements Cloneable {

private static Singlton singlton = null;
private Singlton(){}

public static Singlton getInstance(){
    if(singlton == null){
        singlton = new Singlton();
    }
    return singlton;
}


    protected Object clone() throws CloneNotSupportedException {
        throw new CloneNotSupportedException ("I do not allow to clone, this is SINGLTON");
    }

}
used Java2html to format the code

The other good type I read in the "Spring in Action" book
package test.patterns;

public class SingltonInner {

  private SingltonInner(){}
  
  private static class InnerSingltonInstance{
    static SingltonInner singlton = new SingltonInner();
  }
  
  public static SingltonInner getInstance(){
    return InnerSingltonInstance.singlton;
  }
}









Java2html





Caching Java Objects.

Caching Java Objects for faster retrieval needs just two things, override the hashCode method and equals method of the class’s object to be cached. Things that I would consider while overriding the hashCode is a) to use the fields that make the unique key and b) avoid String fields as much as possible. This example illustrates the same.
package test.classCache;
public class ProductDetails {
  private long productId = -1;
  private long productCode = -1;
  private String productName = null;
  private String productDescription = null;
  public long getProductCode() {
    return productCode;
  }
  public void setProductCode(long productCode) {
    this.productCode = productCode;
  }
  public String getProductDescription() {
    return productDescription;
  }
  public void setProductDescription(String productDescription) {
    this.productDescription = productDescription;
  }
  public long getProductId() {
    return productId;
  }
  public void setProductId(long productId) {
    this.productId = productId;
  }
  public String getProductName() {
    return productName;
  }
  public void setProductName(String productName) {
    this.productName = productName;
  }  
  public int hashCode() {
    return Long.valueOf((this.productCode+this.productId)).hashCode();
  }  
  public boolean equals(Object o) {
    ProductDetails pDetsils = (ProductDetailso;
    return ( (this.productCode == pDetsils.productCode&& (this.productId == pDetsils.productId));
  }
}

Java2html

Spring DI

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.

Followers