An Interview Question on Spring Singleton

Spring Singleton


While taking interview on Spring core, Often I ask a question

What do you mean by Spring Singleton scope?

Most of the time I got an answer like Spring singleton scope manages only one object in the container.

Then after getting this answer I will ask the next question,

Please tell me what will be the output of the following program



Spring.xml file

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
   
    <bean id="scopeTest" class="com.example.scope.Scope" scope="singleton">
    <property name="name" value="Shamik Mitra"/>    
    </bean>    
    <bean id="scopeTestDuplicate" class="com.example.scope.Scope" scope="singleton">
          <property name="name" value="Samir Mitra"/>    
    </bean>
</beans>


Scope.java

package com.example.scope;
public class Scope {
   private String name;

   public String getName() {
      return name;
   }

   public void setName(String name) {
      this.name = name;
   }

   @Override
   public String toString() {
      return "Scope [name=" + name + "]";
   }

}

Main class

package com.example.scope;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Main {

   public static void main(String[] args) {
      ApplicationContext ctx = new ClassPathXmlApplicationContext(
              "configFiles/Scope.xml");

      Scope scope = (Scope) ctx.getBean("scopeTest");
      Scope scopeDuplicate = (Scope) ctx.getBean("scopeTestDuplicate");      
      System.out.println(scope==scopeDuplicate);
      System.out.println(scope  + "::"+ scopeDuplicate);
     

   }

}


Here I create two beans of Scope class and make spring scope as singleton now checking the references.


Now Interviewee got confused, and I will get three types of answer

This code will not compile throw error at runtime, as you can not define two spring beans of the same class with scope singleton in XML. (Very rare).
References check will return true, as container maintains one object so both bean definition will return the same object so memory location would be same.(Often)
They said References check will return false and Spring singleton is not worked as they have told earlier.(few)



The third answer is the correct answer, Spring singleton is not worked as Java Singleton.

If we see the output of the program we will understand that it will return two different instances, So in a  container, there may be more than one object in spite of the scope is the singleton.




Output:

Reference Check ::false
Scope [name=Shamik Mitra]::Scope [name=Samir Mitra]


So again Question is What do you mean by Spring Singleton Scope?

According to Spring documentation

When a bean is a singleton, only one shared instance of the bean will be managed, and all requests for beans with an id or ids matching that bean definition will result in that one specific bean instance being returned by the Spring container.
To put it another way, when you define a bean definition and it is scoped as a singleton, then the Spring IoC container will create exactly one instance of the object defined by that bean definition. This single instance will be stored in a cache of such singleton beans, and all subsequent requests and references for that named bean will result in the cached object being returned.


So it is clear that for a given id Spring container maintains only one shared instance in singleton cache.

In my example, I use two different ids (scopeTest, ScopeTestDuplicate) so Spring container creates two instances of the same class and bound it with respective ids and stores it in singleton cache.

You can think Spring Container manage Key-value pair where Key is the id or name of the bean and value is bean itself , so for a given key, it maintains singleton. So if we use that key as a reference of other beans the same bean will be injected to other beans.





In a one words , Spring guarantees exactly one shared bean instance for the given Id per IoC container unlike Java Singleton where Singleton hard codes the scope of an object such that one and only one instance of a particular class will ever be created per ClassLoader.

Picture taken from Spring docs

Java:Pushing runtime behaviour without Lambda

Java:Pushing runtime behaviour without Lambda



In Java8 one of the best features is Lambda Expression The Idea of Lambda expression is passing a behavior to a method.

This has been adopted from Functional programming, In Functional programming, we can pass a function  as an argument of another function or can returns a function. The function takes a function as an argument or returns a function called
Higher order function.


The benefit of this type of design is you can pass behavior and values together, so a single function can perform all types of actions on those values.

Say, I want to create the calculator so in java we have to create methods like add, subtract, multiply etc. But in the functional program paradigm, we create one method which takes another method as an argument where we define what to do.

Pseudo code
Higher order function

function void caculate (a,b,f){
    f(a,b);
}

Calling

calculate(10,20,funtion(y,z){// define and pass the method on fly

y+z;
});


In Java8 using Lambda, we can do the same if you want to know details about Lambda can consult my post  http://javaonfly.blogspot.in/2016/08/java8-lambda.html


But here we will discuss How we can achieve the same thing without Lambda. As may, many projects has not adopted java 8 due to some restrictions.

We can achieve the same by using  Interface and Anonymous class.

Step 1: Create an Interface which will provide the contract for the behavior/strategy, i.e add, subtract, multiply functionality.

So How we will achieve the same



package com.example.runtime.behaviour;

public interface IStrategy {
   
   public void operation(int operand1,int operand2);

}


Step 2: Next I will create a Calculator class where we create a method called calculate which takes two operands and the IStrategy interface as arguments.

It acts like functional programming Higher order function where we can pass method/behavior runtime.

While calling this calculate method I pass the actual implementation of IStrategy interface by using Anonymous class.

By this way, we can push behavior on runtime without Lambda Expression.


package com.example.runtime.behaviour;

public class Calculator {
   
   public void caculate(int operand1,int operand2,IStrategy runtimeBehaviour){
      runtimeBehaviour.operation(operand1, operand2);
     
   }
   
   public static void testAllOperation(){
     
      Calculator calc = new Calculator();
      calc.caculate(10, 20, new IStrategy(){

          @Override
          public void operation(int operand1, int operand2) {
              int result = operand1+operand2;
              System.out.println("ADD:: " + result);
             
          }
         
      });
     
     
      calc.caculate(10, 20, new IStrategy(){

          @Override
          public void operation(int operand1, int operand2) {
              int result = operand1*operand2;
              System.out.println("Multiply:: " + result);
             
          }
         
      });
   }
   
   public static void main(String[] args) {
      Calculator.testAllOperation();
   }

}



Look at the testAllOperationMethod here we pass two operands 10,20 and implementation of IStrategy one are for add another for multiplication.

So rather creating  4 different methods add, multiply, subtract, the division we can create one method which will support all possible operations taken on operand1 and operand2.

In Future, if any new operation like modulus will be added easily in this approach but if we use one method for one operation then you need to add a new method called modulus to Calculator class which will break Open close principle.

Spring @Transactional & Exception

Spring Transactional Annotation & Exception


What is Transaction?

The transaction is unit work which will success or fails as the unit. So suppose we are dealing with two accounts for transfer money from one to another.  Now if Money from one account is already debited but while it is credited to an another account there was Exception so the ideal scenario would be debited action should rollback. Otherwise, it would be an Inconsistent state.

So if we use Transaction in our business logic we can ensure, logic under the Transaction work as a unit it will be rollback if anything found wrong.

In one word.

Either Unit of work Succeeds completely or failure completely no intermediate state.


Now the question comes How we can handle Transaction.

There are two ways to Handle it

BMT: Bean managed Transaction.
CMT: Container Managed Transaction.



BMT: If we need a finer control over business logic or want to introduce savepoints this type of technique should be adopted where bean provider has a responsibility to start, commit, rollback the transaction.

CMT: If we want to delegate the responsibility to container we use it. Sometimes we called it Declarative Transaction.


We all know in Spring using @Transactional annotation we can adopt Declarative transaction technique.

In this article, I will not show how to configure it but tell about the precaution you want to take while using @Transactional annotation.

Study the pseudo code.
@Transactional
pbublic void transferMoney(Account to,Account from,int amount) throws Exception{
        debiFromAccount(to,amount)
        creditFromAccount(from,amount);
       
    }
   
    public debiFromAccount(Account to,int amount){
        //do staff and debited money from data base
    }
   
    public creditFromAccount(Account from,int amount)throws Exception{
        //do straff
        throw new EXception("Error during credit");
    }



Now do a dry run
If Account to initial balance is 1000
Account from is 500
Transfer amount : 100


After error occurred in creditFromAccount(Account from,int amount) what will be the output you expected?

To : 1000
From : 500

Afterall I use @Transactional so in case of Exception it should be rolled back automatically right.

But unfortunately it left a inconsistent state

Output is like

To : 900
From : 500


So obviously you will ask me Why, what is going on here?

Let me clear you, @Transactional only rollback transaction only for the unchecked exception but for checked Exception and it’s subclass it commits data. So although an Exception raised here but as it is a Checked Exception, Spring simply ignores it and commit the data to the database so the system goes inconsistent.

Spring documentation says that,



While the EJB default behavior is for the EJB container to automatically roll back the transaction on a system exception (usually a runtime exception), EJB CMT does not roll back the transaction automatically on an application exception (that is, a checked exception other than java.rmi.RemoteException). While the Spring default behavior for declarative transaction management follows EJB convention (roll back is automatic only on unchecked exceptions), it is often useful to customize this.

So pay attention to the last line “it is often useful to customize this”

So how can we customize it?

It is very simple just use following with @Transactional

@Transactional(rollbackFor = Exception.class)
So if you throw an Exception or Subclass of Exception always use the above with @Transactional annotation to tell Spring to rollback transaction in case for Checked Exception occur.