Why we need Dependency Injection?
Its to overcome monotony behavior. If you are asking for Apple(from Apple.java) you would be served apple object. If you are asking for Mango(from Mango.java) you would be served mango object. Now in case, you are having Fruit and now you are asking Fruit(from Fruit.java) you would be served either apple or mango. Lets take a simple example as below

  1. I have a banking application where I have Account Interface with calculateIntereest Method
  2. I have different account types like SavingsAccount, PersonalLoanAccount and vehicleLoanAccount, HousingLoanAccount
  3. I have a Customer class where he would own a particular account type which wont be known until runtime

Accounts.java

package com.mugil.core;

public interface Accounts 
{
 public Integer calculateInterest();
}

SavingsAccount.java

package com.mugil.core;

public class SavingsAccount implements Accounts 
{
 public Integer calculateInterest() 
 {
  return 8;
 }
}

Customer.java

package com.mugil.core;

public class Customer {
 Accounts accountType;

 public Customer(Accounts paccountType) {
  this.accountType = paccountType;
 }

 public Accounts getAccountType() {
  return accountType;
 }

 public void setAccountType(Accounts accountType) {
  this.accountType = accountType;
 }
}

GetInterestFactory.java

package com.mugil.core;

public class GetInterestFactory {
 Accounts objAccount = null;

 public static void main(String[] args) {
  GetInterestFactory objGetInterest = new GetInterestFactory();
  objGetInterest.showInterestRate();
 }

 public void showInterestRate() {
  String strAccType = "Savings";

  switch (strAccType) {
   case "Savings":
    this.objAccount = new SavingsAccount();
    break;
   case "Vehicle":
    this.objAccount = new VehicleLoanAccount();
    break;
   default:
    this.objAccount = new SavingsAccount();
    break;
  }

  System.out.println("Interest Rate - " + this.objAccount.calculateInterest());
 }
}

Output

Interest Rate - 8
  1. In the above java code we decide the Account Type only when the switch case is executed
  2. Until then the account type is kept as generic value using interface

Now what spring does is the same code can be rewritten to determine the Account Type during runtime in setters and constructors as below

Dependency Injection without Spring using Java Constructor

  1. I have created a new class VehicleLoanAccount.java which has a different interest rate
  2. Now I am going to decide the account type in the Person.java in its constructor as below

VehicleLoanAccount.java

package com.mugil.core;

public class VehicleLoanAccount implements Accounts {
 public Integer calculateInterest() {
  return 11;
 }

}

Dependency Injection without Spring using Java Constructor
GetInterestConsWithoutSpring .java

package com.mugil.core;

public class GetInterestConsWithoutSpring {
 public static void main(String[] args) {
  Customer objPerson = new Customer(new SavingsAccount());
  System.out.println("Interest Rate - " + objPerson.getAccountType().calculateInterest());
 }
}

Output

Interest Rate - 11

Dependency Injection without Spring using Java Setter

  1. Now I am going to decide the account type in the GetInterest.java in its setter method
  2. I would be passing the value of the actual type inside the setter at runtime to decide the account type
  3. The Only thing which I have changed in the addition of new constructor to the Customer Class
  4. Setter method would be passed with specific account type during runtime

Customer.java

package com.mugil.core;

public class Customer {
 Accounts accountType;

 public Customer(Accounts paccountType) {
  this.accountType = paccountType;
 }

 public Customer() {}

 public Accounts getAccountType() {
  return accountType;
 }

 public void setAccountType(Accounts accountType) {
  this.accountType = accountType;
 }
}

Dependency Injection without Spring using Setter Method
GetInterestSettWithoutSpring .java

package com.mugil.core;

public class GetInterestSettWithoutSpring {
 public static void main(String[] args) {
  Customer customer = new Customer();
  customer.setAccountType(new SavingsAccount());
  System.out.println("Interest Rate - " + customer.getAccountType().calculateInterest());
 }
}

Output

Interest Rate - 8

Ways of Bean Injection using Spring
In Spring we can let the container create the bean in two ways

  1. Bean definition in XML
  2. Bean definition using @Component
  3. Bean definition using Java

Bean definition in XML
beans.xml

<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-2.5.xsd
	http://www.springframework.org/schema/context
	http://www.springframework.org/schema/context/spring-context-2.5.xsd">
	<bean id="customer" class="com.mugil.core.Customer" autowire="constructor">				
	</bean>
	<bean  id="savingsType" class="com.mugil.core.SavingsAccount"/>
	<bean  id="vehicleLoanAccount" class="com.mugil.core.VehicleLoanAccount"/>		
</beans>

context:component-scan used for detecting bean
Bean definition using @Component
beans.xml

<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-2.5.xsd
	http://www.springframework.org/schema/context
	http://www.springframework.org/schema/context/spring-context-2.5.xsd">
	<context:annotation-config />
	<context:component-scan base-package="com.mugil.core"></context:component-scan>			
</beans>

@Component marking bean
Customer.java

package com.mugil.core;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;

@Component
public class Customer 
{

 @Autowired
 @Qualifier("savings")
 Accounts accountType;
.
.
.
}

@Component marking bean
SavingsAccount.java

package com.mugil.core;

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

@Component
@Qualifier("savings")
public class SavingsAccount implements Accounts
{	
	public Integer calculateInterest() 
	{
		return 9;
	}
}

Bean definition using Java

Ways of Bean Injection using Spring
Now, what if we do the same thing from XML and using annotations. Spring offers 3 ways by which dependency injection could be done

  1. XML
    1. Constructor
    2. Setter
    3. Autowiring
      1. byType
      2. byName
      3. Constructor
      4. No
  2. Annotation Based
    1. byType
    2. byName
  3. Java Based

Constructor Based – Dependency Injection using XML

  1. In the below code beans are loaded when the application is deployed and the JVM starts
  2. The beans are uniquely identified using their IDS, in our case it is customer
  3. The parameter for constructor is defined inside constructor-arg in XML

Beans.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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
   <bean id="customer" class="com.mugil.core.Customer">
      <constructor-arg>
         <bean id="savingAccount" class="com.mugil.core.SavingsAccount" />
      </constructor-arg>
   </bean>
</beans>

GetInterestConsWithSpring.xml

package com.mugil.core;

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

public class GetInterestConsWithSpring {
 public static void main(String[] args) {
  ApplicationContext context = new ClassPathXmlApplicationContext("SpringBeans.xml");

  Customer customer = (Customer) context.getBean("customer");

  System.out.println("Interest Rate - " + customer.getAccountType().calculateInterest());
 }
}

Output

Interest Rate - 8

Setter Based – Dependency Injection using XML

  1. For setter injection the only things we need to change is XML
  2. XML should be modified to take value by setter rather than constructor as before using property tag

Beans.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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
   <bean id="customer" class="com.mugil.core.Customer">
      <property name="accountType" ref="savingAccount" />
   </bean>
   <bean id="savingAccount" class="com.mugil.core.SavingsAccount" />
</beans>

GetInterestSettWithSpring.xml

package com.mugil.core;

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

public class GetInterestSettWithSpring {
 public static void main(String[] args) {
  ApplicationContext context = new ClassPathXmlApplicationContext(
   "SpringBeans.xml");

  Customer customer = (Customer) context.getBean("customer");

  System.out.println("Interest Rate - " + customer.getAccountType().calculateInterest());
 }
}

Output

Interest Rate - 8

Autowiring byName

  1. In autoWiring byName the Name of the Instance Varable(accountType) and the ID of the bean in XML should be same
  2. If there is no bean matching the name is found it will throw NullPointerException

Customer.java

package com.mugil.core;

public class Customer {
 Accounts accountType;

 public Customer(Accounts paccountType) {
  this.accountType = paccountType;
 }

 public Customer() {}

 public Accounts getAccountType() {
  return accountType;
 }

 public void setAccountType(Accounts accountType) {
  this.accountType = accountType;
 }
}

Beans.xml

<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="customer" class="com.mugil.core.Customer" autowire="byName">				
	</bean>
	<bean id="accountType" class="com.mugil.core.SavingsAccount"/>
	<bean id="vehicleLoanAccount" class="com.mugil.core.VehicleLoanAccount"/>
</beans>

Output

Interest Rate - 9

What if Bean of Correct Name is notdefined in XML? Inour case it is account Type
Beans.xml

<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="customer" class="com.mugil.core.Customer" autowire="byName">				
	</bean>
	<bean id="savingAccount" class="com.mugil.core.SavingsAccount"/>
	<bean id="vehicleLoanAccount" class="com.mugil.core.VehicleLoanAccount"/>
</beans>

Output

Exception in thread "main" java.lang.NullPointerException
	at com.mugil.core.GetInterestConstAutoWiringXML.main(GetInterestConstAutoWiringXML.java:13)

Autowiring byType

  1. In autoWiring is byType then there should be at least one bean defined for the matching type, in our case it is Accounts
  2. If there is no bean defined of the type then it will throw null pointer exception
  3. If there is more than one matching bean of the same type is found it will throw No unique bean of type

Beans.xml

<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="customer" class="com.mugil.core.Customer" autowire="byType">				
	</bean>
	<bean id="savingsType" class="com.mugil.core.SavingsAccount"/>
</beans>

Output

Interest Rate - 9

What if No bean of right Type is defined in XML or More than one bean of same type defined?
Beans.xml
No bean of right Type is defined in XML

<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="customer" class="com.mugil.core.Customer" autowire="byType">				
	</bean>
</beans>

Output

Exception in thread "main" java.lang.NullPointerException
	at com.mugil.core.GetInterestConstAutoWiringXML.main(GetInterestConstAutoWiringXML.java:13)

Beans.xml
More than one bean of same type defined

<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="customer" class="com.mugil.core.Customer" autowire="byType">				
	</bean>
	<bean id="savingsType" class="com.mugil.core.SavingsAccount"/>
	<bean id="vehicleLoanAccount" class="com.mugil.core.VehicleLoanAccount"/>
</beans>

Output

Exception in thread "main" org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'customer' defined in class path resource [SpringBeans.xml]: Unsatisfied dependency expressed through bean property 'accountType': : No unique bean of type [com.mugil.core.Accounts] is defined: expected single matching bean but found 2: [accountType, vehicleLoanAccount]; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [com.mugil.core.Accounts] is defined: expected single matching bean but found 2: [accountType, vehicleLoanAccount]

Autowiring Contructor

  1. In autoWiring using Constructor spring tries to find bean using type.In our case it is Account type
  2. If there is no bean defined of the type then spring will not guess and it will throw null pointer exception
  3. If there is more than one matching bean then spring will not guess and it will throw null pointer exception
  4. If there is more than one constructor spring wont guess the bean and it will throw null pointer exception

Beans.xml

<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="customer" class="com.mugil.core.Customer" autowire="constructor">				
	</bean>
	<bean id="savingsType" class="com.mugil.core.SavingsAccount"/>
</beans>

Output

Interest Rate - 9

Beans.xml
Two bean of same type in constructor injection

<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="customer" class="com.mugil.core.Customer" autowire="constructor">				
	</bean>
	<bean id="savingsType" class="com.mugil.core.SavingsAccount"/>
<bean id="vehicleLoanAccount" class="com.mugil.core.VehicleLoanAccount"/>
</beans>

Beans.xml
No bean of matching type in constructor injection

<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="customer" class="com.mugil.core.Customer" autowire="constructor">				
	</bean>
</beans>

Output

Exception in thread "main" java.lang.NullPointerException
	at com.mugil.core.GetInterestConstAutoWiringXML.main(GetInterestConstAutoWiringXML.java:13)

Autowiring using autodetect
When the bean is configured to autowire by autodetect spring will attempt to autowire by constructor first.If no suitable constructor to bean is found then spring will attempt to autowire byType.
Beans.xml

<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="customer" class="com.mugil.core.Customer" autowire="autodetect">				
	</bean>
</beans>

Annotation Based – byType

  1. In Annotation based autowiring the beans would be injected by xml and would be available in container
  2. context:annotation-config is used to activate annotations in beans already registered in the application context (no matter if they were defined with XML or by package scanning)
  3. Now by using @Autowired tag we inject the bean as dependency where it is required.It is used either over variable in class or over setter or over constructor
  4. The default @Autowired decides the bean based on its type.If more than one bean if found it will throw no unique bean found exception.If no bean found it will throw nullpointer exception
  5. Incase of more than one bean of same type, we can narrow down the selection by using @Qualifier annotation and converting to byName @Autowiring

Beans.xml

<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-2.5.xsd
	http://www.springframework.org/schema/context
	http://www.springframework.org/schema/context/spring-context-2.5.xsd">

	<context:annotation-config />
	<bean id="customer" class="com.mugil.core.Customer" autowire="constructor">				
	</bean>
	<bean id="savingsType" class="com.mugil.core.SavingsAccount"/>	
</beans>

Customer.java

package com.mugil.core;

import org.springframework.beans.factory.annotation.Autowired;

public class Customer 
{
 @Autowired
 private Accounts accountType;

 public Customer(Accounts paccountType) {
  this.accountType = paccountType;
 }

 public Customer() {}

 public Accounts getAccountType() {
  return accountType;
 }
 
 public void setAccountType(Accounts accountType) {
  this.accountType = accountType;
 }
}

Annotation Based – byName

  1. In the below code we have two bean of same type
  2. Using @autowired would try to find bean byType.Since there are two beans it would throw no unique bean found exception
  3. Now we need to use @Qualifier passing the name (or) id of the bean as parameter
  4. Incase only Id of bean is there then same would be taken for name, If Name is there then name of bean would be given preference, incase no bean matches name then Id would be given preference

Beans.xml

<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-2.5.xsd
	http://www.springframework.org/schema/context
	http://www.springframework.org/schema/context/spring-context-2.5.xsd">

	<context:annotation-config />
	<bean id="customer" class="com.mugil.core.Customer" autowire="constructor">				
	</bean>
	<bean name="savings" id="savingsType" class="com.mugil.core.SavingsAccount"/>
	<bean name="vehicle" id="vehicleLoanAccount" class="com.mugil.core.VehicleLoanAccount"/>		
</beans>

Customer.java

package com.mugil.core;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;

public class Customer 
{

 @Autowired
 @Qualifier("savings")
 Accounts accountType;
.
.
.
}

The below code will work by taking bean id into consideration despite the name doesn’t match.
Customer.java

package com.mugil.core;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;

public class Customer 
{

 @Autowired
 @Qualifier("savingsType")
 Accounts accountType;
.
.
.
}

What if there are two bean with the Same Name?
It will not throw exception during compilation but during runtime it will throw bean name already in use exception
Output

Exception in thread "main" org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Bean name 'savings' is already used in this file
Offending resource: class path resource [SpringBeans.xml]

What if there are two bean with the Same ID?

  1. Eclipse will complain for violating ID should be unique and you are violating
  2. If you build the code still builds but when you run will endup with Caused by: org.xml.sax.SAXParseException; lineNumber: 13; columnNumber: 69; cvc-id.2: There are multiple occurrences of ID value ‘savingsType’

Beans.xml

<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-2.5.xsd
	http://www.springframework.org/schema/context
	http://www.springframework.org/schema/context/spring-context-2.5.xsd">

	<context:annotation-config />
	<bean id="customer" class="com.mugil.core.Customer" autowire="constructor">				
	</bean>
	<bean id="savingsType" class="com.mugil.core.SavingsAccount"/>
	<bean id="savingsType" class="com.mugil.core.VehicleLoanAccount"/>		
</beans>

Using @Component Scan to detect and load beans

  1. We can make spring to detect beans on its own by using @component annotation rather then defining in XML with bean tags
  2. Using context:component-scan with base package pointed to beans package will load the bean marked with @component annotation
  3. If there is bean of one type then it would work fine during autowiring, if there is more than one bean of same type then we should uniquely identify the bean using @qualifier annotation
  4. @qualifier annotation should be used both in the place where the bean is referred and also in the place where it is defined.In our case it is Customer.java and SavingsAccount.java

Beans.xml

<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-2.5.xsd
	http://www.springframework.org/schema/context
	http://www.springframework.org/schema/context/spring-context-2.5.xsd">
	<context:annotation-config />
        <context:component-scan base-package="com.mugil.core"></context:component-scan>	
</beans>

Customer.java

package com.mugil.core;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;

@Component
public class Customer 
{

 @Autowired
 @Qualifier("savings")
 Accounts accountType;
.
.
.
}

SavingsAccount.java

package com.mugil.core;

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

@Component
@Qualifier("savings")
public class SavingsAccount implements Accounts
{	
	public Integer calculateInterest() 
	{
		return 9;
	}
}

What is the difference between applicationcontext and webapplicationcontext in Spring?

  1. The WebApplicationContext is an extension of the plain ApplicationContext that has some extra features necessary for web applications. It differs from a normal ApplicationContext in that it is capable of resolving themes (see Using themes), and that it knows which Servlet it is associated with (by having a link to the ServletContext). The WebApplicationContext is bound in the ServletContext, and by using static methods on the RequestContextUtils class you can always look up the WebApplicationContext if you need access to it.
  2. ApplicationContext (Root Application Context) : Every Spring MVC web application has an applicationContext.xml file which is configured as the root of context configuration. Spring loads this file and creates an applicationContext for the entire application. This file is loaded by the ContextLoaderListener which is configured as a context param in web.xml file. And there will be only one applicationContext per web application.

    WebApplicationContext : WebApplicationContext is a web aware application context i.e. it has servlet context information. A single web application can have multiple WebApplicationContext and each Dispatcher servlet (which is the front controller of Spring MVC architecture) is associated with a WebApplicationContext. The webApplicationContext configuration file *-servlet.xml is specific to a DispatcherServlet. And since a web application can have more than one dispatcher servlet configured to serve multiple requests, there can be more than one webApplicationContext file per web application.

  3. Spring allows you to build multilevel application context hierarchies, so the required bean will be fetched from the parent context if it’s not present in the current application context. In web apps as default there are two hierarchy levels, root and servlet
  4. Web Application context extended Application Context which is designed to work with the standard javax.servlet.ServletContext so it’s able to communicate with the container.
    public interface WebApplicationContext extends ApplicationContext {
        ServletContext getServletContext();
    }
    
  5. Beans, instantiated in WebApplicationContext will also be able to use ServletContext if they implement ServletContextAware interface
    package org.springframework.web.context;
    public interface ServletContextAware extends Aware 
    { 
         void setServletContext(ServletContext servletContext);
    }
    

How to define RootApplicationContext?
This two level separation comes out of the box when you use the spring servlet classes: to configure the root application context you should use context-param tag in your web.xml

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
        /WEB-INF/root-context.xml
            /WEB-INF/applicationContext-security.xml
    </param-value>
</context-param>

The rootapplicationcontext is created by ContextLoaderListener which is declared in web.xml and servletApplicationContexts using servlet tag as below

<!-- rootapplicationcontext-->
<listener>
   <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener> 

<!-- servletApplicationContext-->
<servlet>
   <servlet-name>myservlet</servlet-name>
   <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
   <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>app-servlet.xml</param-value>
   </init-param>
</servlet>

1.Why we are unable to add primitives as generic type
Allowed

 List<Integer> arrAges = new ArrayList<Integer>();

Not allowed

 List<int> arrAges = new ArrayList<int>();

This is to maintain backwards compatibility with previous JVM runtimes in the sense it could be referred by parent class instance Object. Generics in Java are encountered at compile time The compiler converts from generic type to right type as shown in the example below

List<ClassA> list = new ArrayList<ClassA>();
list.add(new ClassA());
ClassA a = list.get(0);

will be turned in to

List list = new ArrayList();
list.Add(new ClassA());
ClassA a = (ClassA)list.get(0);

So anything that is used as generics has to be convert able to Object (in this example get(0) returns an Object), and the primitive types aren’t. So they can’t be used in generics.

2.How to have a Ordered Collections

  1. keep the insertion order: LinkedHashSet and CopyOnWriteArraySet (thread-safe)
  2. keep the items sorted within the set: TreeSet, EnumSet (specific to enums) and ConcurrentSkipListSet (thread-safe)

Similarities between TreeMap and TreeSet in Java

  1. Both TreeMap and TreeSet are sorted data structure, which means they keep there element in predefined Sorted order. Sorting order can be natural sorting order defined by Comparable interface or custom sorting Order defined by Comparator interface. Both TreeMap and TreeSet has overloaded constructor which accept a Comparator, if provided all elements inside TreeSet or TreeMap will be compared and Sorted using this Comparator.
  2. Both TreeSet and TreeMap implements base interfaces e.g. TreeSet implements Collection and Set interface so that they can be passed to method where a Collection is expected and TreeMap implements java.util.Map interface, which means you can pass it when a Map is expected
  3. TreeSet is practically implemented using TreeMap instance, similar to HashSet which is internally backed by HashMap instance.
  4. Both TreeMap and TreeSet are non synchronized Collection, hence can not be shared between multiple threads. You can make both TreeSet and TreeMap synchronized by wrapping them into Synchronized collection by calling Collections.synchroinzedMap() method.
  5. Iterator returned by TreeMap and TreeSet are fail-fast, means they will throw ConcurrentModificationException when TreeMap or TreeSet is modified structurally once Iterator is created.
  6. Both TreeMap and TreeSet are slower than there Hash counter part like HashSet and HashMap and instead of providing constant time performance for add, remove and get operation they provide performance in O(log(n)) order.

TreeSet vs TreeMap

  1. Major difference between TreeSet and TreeMap is that TreeSet implements Set interface while TreeMap implements Map interface in Java.
  2. TreeMap and TreeSet is the way they store objects. TreeSet stores only one object while TreeMap uses two objects called key and Value. Objects in TreeSet are sorted while keys in TreeMap remain in sorted Order.
  3. former implements NavigableSet while later implements NavigableMap in Java.
  4. duplicate objects are not allowed in TreeSet but duplicates values are allowed in TreeMap.

1.How to get elements from HashMap

public static void printMap(Map mp) 
{
    Iterator it = mp.entrySet().iterator();

    while (it.hasNext()) 
    {
        Map.Entry pairs = (Map.Entry)it.next();
        System.out.println(pairs.getKey() + " = " + pairs.getValue());

        //Avoids a ConcurrentModificationException
        it.remove(); 
    }
}

2.Adding keys to HashMap Finding Next Key
To find the next key while using HashMap with Integer as Key the following function can be used.

  1. Iterate through List of Keys
  2. Sort the Keys
  3. Find the Highest value by looking into Key at size-1
  4. The next key to be used is received by adding 1 to Key(lastMaxElem) at size-1
private Integer getNextKey()
{
    List<Integer> keyList = new ArrayList<Integer>();
    int lastMaxElem = 0;
		
    HashMap WaterfallHM = (HashMap) getFromWorkFlowScope("WaterfallHM");		
    Set<Integer> keys = WaterfallHM.keySet();
        
    for ( Integer key : keys) {
	keyList.add(key);
    }
		
    Collections.sort(keyList); // Sort the arraylist
    lastMaxElem = keyList.get(keyList.size() - 1);
    lastMaxElem++; 
		
    return new Integer(lastMaxElem);
}

3.How to Initialize a Constants in HashMap

public class Test 
{
    private static final Map<Integer, String> MY_MAP = createMap();

    private static Map<Integer, String> createMap() {
        Map<Integer, String> result = new HashMap<Integer, String>();
        result.put(1, "one");
        result.put(2, "two");
        return Collections.unmodifiableMap(result);
    }
}

4.Why Map Interface doesnot extend Collections Framework
Collection assume elements of one value. Map assumes entries of key/value pairs. They could have been engineered to re-use the same common interface however some methods they implement are incompatible e.g.

Collection.remove(Object) - removes an element.
Map.remove(Object) - removes by key, not by entry.

There are some methods in common; size(), isEmpty(), clear(), putAll/addAll()

Collection interface is largely incompatible with the Map interface. If Map extended Collection, what would the add(Object) method do

5.Why need ConcurrentHashMap and CopyOnWriteArrayList
he synchronized collections classes, Hashtable, and Vector, and the synchronized wrapper classes, Collections.synchronizedMap() and Collections.synchronizedList(), provide a basic conditionally thread-safe implementation of Map and List. However, several factors make them unsuitable for use in highly concurrent applications, for example, their single collection-wide lock is an impediment to scalability and it often becomes necessary to lock a collection for a considerable time during iteration to prevent ConcurrentModificationException.ConcurrentHashMap(uses Segments) and CopyOnWriteArrayList implementations provide much higher concurrency while preserving thread safety, with some minor compromises in their promises to callers.

Problems
Q1.Calculate total distance traveled by beeTwo trains are on the same track and they are coming toward each other. The speed of the first train is 50 KMs/h and the speed of second train is 70 KMs/h. A bee starts flying between the trains when the distance between two trains is 100 KMs. The bee first flies from the first train to the second train. Once it reaches the second train, it immediately flies back to the second train … and so on until trains collide. Calculate the total distance traveled by the bee. Speed of bee is 80 KMs/h.

Solutions
Calculate total distance traveled by bee

                                        80km/h
                        50km/h       <---------->        70km/h 
------------------------Train1->         bee             <-Train2-------------------------
                                <----------------------->  
                                        100km/h

Time left for the train to meet each other = 100/(50+70) = 100/120=0.83 = 49.8 Minutes
The Fly will zigzag between train till that time at speed of 80km/h = (80/60)*49.8 = 1.33*49.8 = 66.4KM

Lets solve the same problem with some easy values as below

                                        40km/h
                        20km/h       <---------->        20km/h 
------------------------Train1->         bee             <-Train2-------------------------
                                <----------------------->  
                                        100km/h

Time left for the train to meet each other = 100/(20+20) = 100/40=2.5(2Hrs30 Minutes)
The Fly will zigzag between train till that time at speed of 40km/h = (40/60)*150 = 0.66*150 = 100KM

In Spring MVC Exceptions can be handled at three levels.

1.Controller Based
We can define exception handler methods in our controller classes. All we need is to annotate these methods with @ExceptionHandler annotation. This annotation takes the Exception class as an argument. So if we have defined one of these for Exception class, then all the exceptions thrown by our request handler method will have handled.
These exception handler methods are just like other request handler methods and we can build error response and respond with a different error page. We can also send a JSON error response, that we will look later on in our example.

@ExceptionHandler({SpringException.class})
.
.
@RequestMapping(value = "/addStudent", method = RequestMethod.POST)
@ExceptionHandler({SpringException.class})
public String addStudent(@ModelAttribute("HelloWeb") Student student, ModelMap model) 
{
 if (student.getName().length() < 5)  
  throw new SpringException("Given name is too short");
 else
  model.addAttribute("name", student.getName());
 
 if (student.getAge() < 10)
  throw new SpringException("Given age is too low");
 else
  model.addAttribute("age", student.getAge());

  model.addAttribute("id", student.getId());
  return "result";
}
.
.
.

If there are multiple exception handler methods defined, then handler method that is closest to the Exception class is used. For example, if we have two handler methods defined for IOException and Exception and our request handler method throws IOException, then the handler method for IOException will get executed.

2.Global Exception Handler-The handler methods in Global Controller Advice is same as Controller based exception handler methods and used when controller class is not able to handle the exception.@ControllerAdvice is a annotation provided by Spring allowing you to write global code that can be applied to a wide range of controllers, varying from all controllers to a chosen package or even a specific annotation. The annotation could be applied at Package Level, Class Level and at Annotation Level.

Package Level Application

@ControllerAdvice("my.chosen.package")
@ControllerAdvice(value = "my.chosen.package")
@ControllerAdvice(basePackages = "my.chosen.package")

Package Level Application – This will apply across all the classes inside the package where MyClass.class is placed.

@ControllerAdvice(basePackageClasses = MyClass.class)

Controller Level
Controller advice can be limited to certain controllers (not methods) by using one of the values of the @ControllerAdvice annotation, e.g.

@ControllerAdvice(assignableTypes = {MyController1.class, MyController2.class})

Controller identified by Annotation
If you want to apply it to controllers with certain annotations. The below snippet would only assist controllers annotated with @RestController (which it covers by default) but will not include @Controller annotated classes.

@ControllerAdvice(annotations = RestController.class)

3.HandlerExceptionResolver – can be implemented by the application to resolve exceptions thrown during processing an HTTP request. The exception can be thrown by one of the application’s handler methods or outside of it but during processing a request. The method, HandlerExceptionResolver#resolveException(), returns an instance of ModelAndView specifying an error page. The Implementations are typically registered as beans in the application context. The application registered HandlerExceptionResolvers will only be invoked if the exception is not already handled by the default HandlerExceptionResolvers. We can, however, change the order of the resolvers so that a given resolver can be invoked first.

@ExceptionHandler vs HandlerExceptionResolver vs @ControllerAdvice
@ExceptionHandler works at the Controller level and it is only active for that particular Controller, not globally for the entire application.

@ControllerAdvice used for global error handling in the Spring MVC application.It also has full control over the body of the response and the status code.

HandlerExceptionResolver-This will resolve any exception thrown by the application. It is used to resolve standard Spring exceptions to their corresponding HTTP Status Codes. It does not have control over the body of the response, means it does not set anything to the body of the Response.It does map the status code on the response but the body is null.

Posted in MVC.

Questions

  1. Three ants are sitting at the three corners of an equilateral triangle. Each ant starts randomly picks a direction and starts to move along the edge of the triangle. What is the probability that none of the ants collide?

Solutions
The ants can only avoid a collision if they all decide to move in the same direction (either clockwise or anti-clockwise). So what is the probability of taking Clockwise direction? 1/2 (0.5).What is the probability of all ants taking the same direction?

Probability of taking the Clockwise direction      = 0.5x0.5x0.5
Probability of taking the Anti-Clockwise direction = 0.5x0.5x0.5
Probability of taking the Same Direction = 0.5x0.5x0.5+0.5x0.5x0.5=0.125+0.125=0.25

Problems

  1. Find the Diagonal difference in the Matrix? Add the Diagonal values and subtract them from right to left and left to right? Print the absolute difference as output

Solutions

Input

 11  2   4 
 4   5   6
 10  8  -12 

Solution

(11+5+-12)-(4+5+10) 
(4)-(19)
(-15)

Output

15

DiagonalDiff.java

class DiagonalDiff
{
 public static int difference(int arr[][], int n) 
 {
  int d1 = 0, d2 = 0;

  for (int i = 0; i < n; i++) 
  {
   d1 += arr[i][i];
   d2 += arr[i][n - i - 1];
  }
  return Math.abs(d1 - d2);
 }
 
 public static void main(String[] args) 
 {
  int n = 3;

  int arr[][] = 
  {
   {11, 2, 4}, 
   {4 , 5, 6}, 
   {10, 8, -12} 
  };

  System.out.print(difference(arr, n));
 }
}