Showing posts with label spring. Show all posts
Showing posts with label spring. Show all posts

Wednesday, 1 June 2016

Method injection with Spring

Spring core comes out-of-the-box with two scopes: singletons and prototypes. Singletons implement the Singleton pattern, meaning there’s only a single instance at runtime (in a JVM). Spring instantiate them during context creation, caches them in the context, and serves them from the cache when needed (or something like that). Prototypes are instantiated each time you access the context to get the bean.
Problems arise when you need to inject a prototype-scoped bean in a singleton-scoped bean. Since singletons are created (and then injected) during context creation: it’s the only time the Spring context is accessed and thus prototype-scoped beans are injected only once, thus defeating their purpose.
In order to inejct prototypes into singletons, and side-by-syde with setter and constructor injection, Spring proposes another way for injection, called method injection. It works in the following way: since singletons are instantiated at context creation, it changes the way prototype-scoped are handled, from injection to created by an abstract method. The following snippet show the unsuccessful way to achieve injection:
public class Singleton {

    private Prototype prototype;

    public Singleton(Prototype prototype) {
        this.prototype = prototype;
    }

    public void doSomething() {
        prototype.foo();
    }

    public void doSomethingElse() {
        prototype.bar();
    }
}
The next snippet displays the correct code:
public abstract class Singleton {

    protected abstract Prototype createPrototype();

    public void doSomething() {
        createPrototype().foo();
    }

    public void doSomethingElse() {
        createPrototype().bar();
    }
}
As you noticed, code doesn’t specify the createPrototype() implementation. This responsibility is delegated to Spring, hence the following needed configuration:
<bean id="prototype" class="ch.frankel.blog.Prototype" scope="prototype" />
<bean id="singleton" class="sample.MySingleton">
 <lookup-method name="createPrototype" bean="prototype" />
</bean>
Note that an alternative to method injection would be to explicitly access the Spring context to get the bean yourself. It’s a bad thing to do since it completely defeats the whole Inversion of Control pattern, but it works (and is essentially the only option when a nasty bug happens on the server - see below).
However, using method injection has several main limitations:
  • Spring achieves this black magic by changing bytecode. Thus, you'll need to have the CGLIB libraryon the classpath.
  • The feature is only available by XML configuration, no annotations (see this JIRAfor more information)
  • Finally, some application servers have bugs related to CGLIB (such as this one)

Monday, 30 May 2016

Difference between a Spring singleton and a Java singeleton (design pattern)

Singleton beans in Spring and classes based on Singleton design pattern are quite different.
The Java singleton is scoped by the Java class loader, the Spring singleton is scoped by the container context.
Which basically means that, in Java, you can be sure a singleton is a truly a singleton only within the context of the class loader which loaded it. Other class loaders should be capable of creating another instance of it (provided the class loaders are not in the same class loader hierarchy), despite of all your efforts in code to try to prevent it. In Spring, if you could load your singleton class in two different contexts and then again we can break the singleton concept. So, in summary, Java considers something a singleton if it cannot create more than one instance of that class within a given class loader, whereas Spring would consider something a singleton if it cannot create more than one instance of a class within a given container/context.
Here is some example:
spring-config.xml
 <?xml version="1.0" encoding="UTF-8"?>  
 <beans xmlns="http://www.springframework.org/schema/beans"  
     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.2.xsd  
       http://www.springframework.org/schema/context   
       http://www.springframework.org/schema/context/spring-context-3.2.xsd">  
   <bean id="a" class="com.pkg.Singleton" scope="singleton" />    
 </beans>  
Bean Singleton
 public class Singleton{  
   private String text;  
   public String getText() {  
     return text;  
   }  
   public void setText(String text) {  
     this.text = text;  
   }  
 }  
Test 
 public class Test {  
   public static void main(String[] args) {  
     ApplicationContext ctx = new ClassPathXmlApplicationContext("spring-config.xml");  
     Singleton a1 = ctx.getBean("a", Singleton.class);  
     a1.setText("text A1");  
     Singleton a2 = ctx.getBean("a", Singleton.class);  
     a2.setText("text A2");  
     System.out.println("a1: " + a1.getText());  
     System.out.println("a2: " + a2.getText());  
   }  
 }  
Output: 
 a1: text A2  
 a2: text A2  
And now let's create another one ApplicationContext: 
 public class Test {  
   public static void main(String[] args) {  
     ApplicationContext ctx = new ClassPathXmlApplicationContext("spring-config.xml");  
     ApplicationContext ctx2 = new ClassPathXmlApplicationContext("spring-config.xml");  
     Singleton a1 = ctx.getBean("a", Singleton.class);  
     a1.setText("text A1");  
     Singleton  a2 = ctx2.getBean("a", Singleton.class);  
     a2.setText("text A2");  
     System.out.println("a1: " + a1.getText());  
     System.out.println("a2: " + a2.getText());  
     // both ctx and ctx2 have same classloaders  
     System.out.println("context1 classloader: " + ctx.getClassLoader());  
     System.out.println("context2 classloader: " + ctx2.getClassLoader());  
   }  
 }  
Output: 
 a1: text A1  
 a2: text A2  
 context1 classloader: sun.misc.Launcher$AppClassLoader@5284e9  
 context2 classloader: sun.misc.Launcher$AppClassLoader@5284e9  

Friday, 29 January 2016

advantage of using spring hibernate over hibernate alone

Spring provides hibernate template and it has many advantages like
1) It removes boiler plate code like getting connection from data source try/catch block for closing connection. So that developer can focus on writing business logic rather then writing boilier plate code every where.

2) Spring hibernateTemplate also throws RunTime exception compared to checkd exception which allows to remove writing try/catch block in each DAO.

3) It also gives richer template class using which developer can write query code easily. This template class also allows to get session explicitly so if developer wants to get session object and work on it then it's possible.