1. Spring sits between the application classes and the O/R mapping tool, undertakes transactions, and manages connection objects.It translates the underlying persistence exceptions thrown by Hibernate to meaningful, unchecked exceptions of type DataAccessException. Moreover, Spring provides IoC and AOP, which can be used in the persistence layer
  2. Hibernate uses Template Pattern – To clean the code and provide more manageable code, Spring utilizes a pattern called Template Pattern. By this pattern, a template object wraps all of the boilerplate repetitive code. Then, this object delegates the persistence calls as a part of functionality in the template. In the Hibernate case, HibernateTemplate extracts all of the boilerplate code, such as obtaining a Session, performing transaction, and handing exceptions.
  3. With Spring, the HibernateTemplate object interacts with Hibernate. This object removes the boilerplate code from DAO implementations.Any invocation of one of HibernateTemplate’s methods throws the generic DataAccessException exception instead of HibernateException (a Hibernate-specific exception).Spring lets us demarcate transactions declaratively, instead of implementing duplicated transaction-management code.
  4. The HibernateTemplate class uses a SessionFactory instance internally to obtain Session objects for Hibernate interaction. Interestingly, you can configure the SessionFactory object via the Spring IoC container to be instantiated and injected into DAO objects.
  5. Spring provides its own exception hierarchy, which sits on the exception hierarchies of the O/R mapping tools.The Spring exception hierarchy is defined as a subclass of org.springframework.dao.DataAccessException. Spring catches any exception thrown in the underlying persistence technology and wraps it in a DataAccessException instance.The DataAccessException object is an unchecked exception, because it extends RuntimeException and you do not need to catch it if you do not want to.
  6. Spring provides distinct DAO base classes for the different data-access technologies it supports. When you use Hibernate with Spring, the DAO classes extend the Spring org.springframework.orm.hibernate3.support.HibernateDaoSupport class. This class wraps an instance of org.springframework.orm.hibernate3.HibernateTemplate, which in turn wraps an org.hibernate.SessionFactory instance.
    org.springframework.orm.hibernate3.support.HibernateDaoSupport   
                              |
       org.springframework.orm.hibernate3.HibernateTemplate
                              |
                 org.hibernate.SessionFactory   
      
  7. HibernateException is thrown for any failure when directly interacting with Hibernate. When Spring is used, HibernateException is caught by Spring and translated to DataAccessException for any persistence failure. Both exceptions are unchecked, so you do not need to catch them if you don’t want to do.
  8. DAO Implementation using DAOSupport
    StudentDao.java

    import java.util.Collection;
    
    public interface StudentDao 
    {
      public Student getStudent(long id);
      public Collection getAllStudents();
      public Collection findStudents(String lastName);
      public void saveStudent(Student std);
      public void removeStudent(Student std);
    }
    

    Using DAOSupport Object
    StudentDao.java

    import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
    import java.util.Collection;
    
    public class HibernateStudentDao extends HibernateDaoSupport implements StudentDao 
    {
      public Student getStudent(long id) 
      {
        return (Student) getHibernateTemplate().get(Student.class, new Long(id));
      }
    
      public Collection getAllStudents()
      {
        return getHibernateTemplate().find("from Student std order by std.lastName, std.firstName");
      }
    
    
      public Collection findStudents(String lastName) 
      {
        return getHibernateTemplate().find("from Student std where std.lastName like ?", lastName + "%");
      }
    
      public void saveStudent(Student std) 
      {
        getHibernateTemplate().saveOrUpdate(std);
      }
    
      public void removeStudent(Student std) 
      {
        getHibernateTemplate().delete(std);
      }
    }
    
  9. all of the persistent methods in the DAO class use the getHibernateTemplate() method to access the HibernateTemplate object.
  10. HibernateTemplate is a Spring convenience class that delegates DAO calls to the Hibernate Session API. This class exposes all of Hibernate’s Session methods, as well as a variety of other convenient methods that DAO classes may need. Because HibernateTemplate convenient methods are not exposed by the Session interface, you can use find() and findByCriteria() when you want to execute HQL or create a Criteria object.
  11. Using the HibernateDaoSupport class as the base class for all Hibernate DAO implementations would be more convenient, but you can ignore this class and work directly with a HibernateTemplate instance in DAO classes. To do so, define a property of HibernateTemplate in the DAO class, which is initialized and set up via the Spring IoC container.
  12. DAO Implementation Using HibernateTemplate

    import org.springframework.orm.hibernate3.HibernateTemplate;
    import java.util.Collection;
    
    public class HibernateStudentDao implements StudentDao 
    {
        
      HibernateTemplate hibernateTemplate;
    
      public Student getStudent(long id) 
      {
        return (Student) getHibernateTemplate().get(Student.class, new Long(id));
      }
    
      public Collection getAllStudents()
      {
        return getHibernateTemplate().find("from Student std order by std.lastName, std.firstName");
      }
    
      public Collection findStudents(String lastName) 
      {
        return getHibernateTemplate().find("from Student std where std.lastName like "+ lastName + "%");
      }
    
      public void saveStudent(Student std) 
      {
        getHibernateTemplate().saveOrUpdate(std);
      }
    
      public void removeStudent(Student std) 
      {
        getHibernateTemplate().delete(std);
      }
    
      public HibernateTemplate getHibernateTemplate() 
      {
        return hibernateTemplate;
      }
    
      public void setHibernateTemplate(HibernateTemplate hibernateTemplate) 
      {
        this.hibernateTemplate = hibernateTemplate;
      }
    }
     
  13. The DAO class now has the setHibernateTemplate() method to allow Spring to inject the configured HibernateTemplate instance into the DAO object.Moreover, the DAO class can abandon the HibernateTemplate class and use the SessionFactory instance directly to interact with Hibernate.

    Using SessionFactory Object

    import org.hibernate.HibernateException;
    import org.hibernate.Session;
    import org.hibernate.Query;
    import org.hibernate.SessionFactory;
    import org.springframework.orm.hibernate3.SessionFactoryUtils;
    
    import java.util.Collection;
    
    public class HibernateStudentDao implements StudentDao 
    {
      SessionFactory sessionFactory;
    
      public Student getStudent(long id) 
      {
        Session session = SessionFactoryUtils.getSession(this.sessionFactory, true);
        try {
          return (Student) session.get(Student.class, new Long(id));
        } catch (HibernateException ex) {
          throw SessionFactoryUtils.convertHibernateAccessException(ex);
        } finally {
          SessionFactoryUtils.closeSession(session);
        }
      }
    
      public Collection getAllStudents()
      {
        Session session = SessionFactoryUtils.getSession(this.sessionFactory, true);
        try {      
          Query query = session.createQuery("from Student std order by std.lastName, std.firstName");
          Collection allStudents = query.list();
          return allStudents;
        } catch (HibernateException ex) {
          throw SessionFactoryUtils.convertHibernateAccessException(ex);
        } finally {
          SessionFactoryUtils.closeSession(session);
        }
      }
    
      public Collection getGraduatedStudents()
      {
        Session session = SessionFactoryUtils.getSession(this.sessionFactory, true);
        try {
          Query query = session.createQuery("from Student std where std.status=1");
          Collection graduatedStudents = query.list();
          return graduatedStudents;
        } catch (HibernateException ex) {
          throw SessionFactoryUtils.convertHibernateAccessException(ex);
        } finally {
          SessionFactoryUtils.closeSession(session);
        }
      }
    
      public Collection findStudents(String lastName) 
      {
        Session session = SessionFactoryUtils.getSession(this.sessionFactory, true);
        try {
          Query query = session.createQuery("from Student std where std.lastName like ?");
          query.setString(1, lastName + "%");
          Collection students = query.list();
          return students;
        } catch (HibernateException ex) {
          throw SessionFactoryUtils.convertHibernateAccessException(ex);
        } finally {
          SessionFactoryUtils.closeSession(session);
        }
      }
    
      public void saveStudent(Student std) 
      {
        Session session = SessionFactoryUtils.getSession(this.sessionFactory, true);
        try {
          session.save(std);
        } catch (HibernateException ex) {
          throw SessionFactoryUtils.convertHibernateAccessException(ex);
        } finally {
          SessionFactoryUtils.closeSession(session);
        }
      }
    
      public void removeStudent(Student std) 
      {
        Session session = SessionFactoryUtils.getSession(this.sessionFactory, true);
        try {
          session.delete(std);
        } catch (HibernateException ex) {
          throw SessionFactoryUtils.convertHibernateAccessException(ex);
        } finally {
          SessionFactoryUtils.closeSession(session);
        }
      }
    
      public void setSessionFactory(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
      }
    }
    
  14. In all of the methods above, the SessionFactoryUtils class is used to obtain a Session object. The provided Session object is then used to perform the persistence operation. SessionFactoryUtils is also used to translate HibernateException to DataAccessException in the catch blocks and close the Session objects in the final blocks. Note that this DAO implementation bypasses the advantages of HibernateDaoSupport and HibernateTemplate. You must manage Hibernate’s Session manually (as well as exception translation and transaction management) and implement much boilerplate code.
  15. org.springframework.orm.hibernate3.SessionFactoryUtils is a Spring helper class for obtaining Session, reusing Session within transactions, and translating HibernateException to the generic DataAccessException.
  16. In cases where you need to work directly with Session objects, you can use an implementation of the org.springframework.orm.hibernate3.HibernateCallback interface as the handler to work with Sessions.
  17. An implicit implementation of HibernateCallback is created and its only doInHibernate() method is implemented. The doInHibernate() method takes an object of Session and returns the result of persistence operation, null if none. The HibernateCallback object is then passed to the execute() method of HibernateTemplate to be executed. The doInHibernate() method just provides a handler to work directly with Session objects that are obtained and used behind the scenes.

    Using HibernateCallback

     public void saveStudent(Student std) 
     {
      HibernateCallback callback = new HibernateCallback() {
       public Object doInHibernate(Session session) throws 
    HibernateException, SQLException {
        return session.saveOrUpdate(std);
       }
      };
      getHibernateTemplate().execute(callback);  
     }
     

What is BeanFactory?
The BeanFactory is the actual container which instantiates, configures, and manages a number of beans.Let have a look at how spring works

How it Works

  1. When the application is Deployed the Spring framework reads the xml file and creates the objects.Those are the objects which you see in the Spring Container
  2. Now when you try to refer any of these objects from the outside object using the new method it will throw an exception since or when you try to create a object using new method, the spring container has no idea about the object which you are trying to access
  3. Now to access the object in the container you will use the BeanFactory Objects

BeanFactory is represented by org.springframework.beans.factory.BeanFactory interface.It is the main and the basic way to access the Spring container.Other ways to access the spring container such as ApplicationContext,ListableBeanFactory, ConfigurableBeanFactory etc. are built upon this BeanFactory interface.

BeanFactory interface defines basic functionality for the Spring Container like

  1. It is built upon Factory Design Pattern
  2. provides DI / IOC mechanism for the Spring.
  3. It loads the beans definitions and their property descriptions from some configuration source (for example, from XML configuration file) .
  4. Instantiates the beans when they are requested like beanfactory_obj.getBean(“beanId”).
  5. Wire dependencies and properties for the beans according to their configuration defined in configuration source while instantiating the beans.
  6. Manage the bean life cycle by bean lifecycle interfaces and calling initialization and destruction methods.

Note that BeanFactory does not create the objects of beans immediately when it loads the configuration for beans from configuration source.Only bean definitions and their property descriptions are loaded. Beans themselves are instantiated and their properties are set only when they are requested such as by getBean() method.

Different BeanFactory Implementations:

XmlBeanFactory using Constructor:

Resource res = new FileSystemResource("c:/beansconfig.xml");
BeanFactory bfObj = new XmlBeanFactory(res);
MyBean beanObj= (MyBean) bfObj.getBean("mybean");
  1. The XmlBeanFactory takes the resource object as Parameter
  2. bfObj points to the Spring Container from which you try to fetch the object
  3. mybean is the ID of the Object specified in the XML File
  4. In the above case BeanFactory loads the beans lazily.BeanFactory will read bean definition of a bean with id “mybean” from beansconfig.xml file, instantiates it and return a reference to that.
  5. There are tow implementation of Resource Intefrace. one is org.springframework.core.io.FileSystemResource as seen above and other is org.springframework.core.io.ClassPathResource which loads Loads the resource from classpath(shown below).
ClassPathResource resorce = new ClassPathResource ("beansconfig.xml");
BeanFactory factory = new XmlBeanFactory(resource);

ClassPathXmlApplicationContext:

ClassPathXmlApplicationContext appContext = new ClassPathXmlApplicationContext(
        new String[] {"applicationContext.xml", "applicationContext-part2.xml"});

//an ApplicationContext is also a BeanFactory.
BeanFactory factory = (BeanFactory) appContext;

null

Note BeanFactory is not recomended for use in latest Spring versions. It is there only for backward compatability. ApplicationContext is preferred over this because ApplicationContext provides more advance level features which makes an application enterprise level application.

IoC is a generic term meaning rather than having the application call the methods in a framework, the framework calls implementations provided by the application.Inversion of Control (IoC) means any sort of programming style where an overall framework or run-time controlled the program flow.

Dependency Injection is a Type of IoC

IoC means that objects do not create other objects on which they rely to do their work. Instead, they get the objects that they need from an outside service (for example, xml file or single app service).

DI means the IoC principle of getting dependent object is done without using concrete objects but abstractions (interfaces). This makes all components chain testable, cause higher level component doesn’t depend on lower level component, only from interface.

Techniques to implement inversion of control

  1. using a factory pattern
  2. using a service locator pattern
  3. using a dependency injection of any given below type:
    1. a constructor injection
    2. a setter injection
    3. an interface injection

DI is a form of IoC, where implementations are passed into an object through constructors/setters/service look-ups, which the object will ‘depend’ on in order to behave correctly.

IoC without using DI, for example would be the Template pattern because the implementation can only be changed through sub-classing.

DI Frameworks are designed to make use of DI and can define interfaces (or Annotations in Java) to make it easy to pass in implementations.

IoC is a generic term meaning rather than having the application call the methods in a framework, the framework calls implementations provided by the application.

Say the Excel Jar files with utility methods used the application uses the methods in the Utility Class and the flow is controlled by the way the method gets called in order the get the things done.

whereas

In framework like spring the implementation is defined in XML files and by using annotation and the framework calls the methods as per defined in xml.

Without Ioc

  Application -> Methods -> Framework      

With Ioc

  Framework -> XML File ->  Method Call (or) Implementation      

Inversion of Control(IoC) Container:
Common characteristic of frameworks IOC manages java objects

  1. From instantiation to destruction through its BeanFactory.
  2. Java components that are instantiated by the IoC container are called beans, and the IoC container manages a bean’s scope, lifecycle events, and any AOP features for which it has been configured and coded.

Flow of control is “inverted” by dependency injection because you have effectively delegated dependencies to some external system

The Inversion of Control (IoC) and Dependency Injection (DI) patterns are all about removing dependencies from your code.

For example, say your application has a text editor component and you want to provide spell checking. Your standard code would look something like this:

public class TextEditor
{
    private SpellChecker checker;
    public TextEditor()
    {
        this.checker = new SpellChecker();
    }
}

What we’ve done here is create a dependency between the TextEditor and the SpellChecker. In an IoC scenario we would instead do something like this:

public class TextEditor
{
    private ISpellChecker checker;
    public TextEditor(ISpellChecker checker)
    {
        this.checker = checker;
    }
}

Now, the client creating the TextEditor class has the control over which SpellChecker implementation to use. We’re injecting the TextEditor with the dependency.

Without IoC: you ask for “apple”, and you are always served apple when you ask more.

With IoC:
You can ask for “fruit”. You can get different fruits each time you get served. for example, apple, orange, or water melon.

Inversion of Control, (or IoC), is about getting
freedom (You get married, you lost freedom and you are being controlled. You divorced, you have just implemented Inversion of Control. That’s what we called, “decoupled”. Good computer system discourages some very close relationship.)

flexibility (The kitchen in your office only serves clean tap water, that is your only choice when you want to drink. Your boss implemented Inversion of Control by setting up a new coffee machine. Now you get the flexibility of choosing either tap water or coffee.)

less dependency (Your partner has a job, you don’t have a job, you financially depend on your partner, so you are controlled. You find a job, you have implemented Inversion of Control. Good computer system encourages in-dependency.)

Dependency Injection

What is Dependency

Quick Example:EMPLOYEE OBJECT WHEN CREATED,
              IT WILL AUTOMATICALLY CREATE ADDRESS OBJECT
   (if address is defines as dependency by Employee object)

Now in the above EMPLOYEE Class is dependent on ADDRESS Class.

You can not create the Address Object unless you create Employee Object

EMPLOYEE Class is dependent and ADDRESS Class is dependency

What is the purpose of DI?
With dependency injection, objects don’t define their dependencies themselves, the dependencies are injected to them as needed.The purpose of Dependency Injection is to reduce coupling in your application to make it more flexible and easier to test.

How does it benefit ? The objects don’t need to know where and how to get their dependencies, which results in loose coupling between objects, which makes them a lot easier to test.

When to use Dependency Injection
One of the most compelling reasons for DI is to allow easier unit testing without having to hit a database and worry about setting up ‘test’ data.Dependency Injection gives you the ability to test specific units of code in isolation.

Dependency injection is basically providing the objects that an object needs (its dependencies) instead of having it construct them itself. It’s a very useful technique for testing, since it allows dependencies to be mocked or stubbed out.

Dependencies can be injected into objects by many means (such as constructor injection or setter injection). One can even use specialized dependency injection frameworks (e.g Spring) to do that, but they certainly aren’t required.

Example
A Car depends on wheels, engine, fuel, battery, etc. to run. Traditionally we define the brand of such dependent objects along with the definition of the Car object

Without Dependency Injection (DI):

class Car
{
  private Wheel wh   = new ApolloWheel();
  private Battery bt = new ExideBattery();

  //The rest
}

Here, the Car object is responsible for creating the dependent objects.

What if we want to change the type of its dependent object – say Wheel – after the initial ApolloWheel() punctures? We need to recreate the Car object with its new dependency say SpareWheel(), but only the Car manufacturer can do that.

Then what does the Dependency Injection do us for…?

When using dependency injection, objects are given their dependencies at run time rather than compile time (car manufacturing time). So that we can now change the Wheel whenever we want. Here, the dependency (wheel) can be injected into Car at run time.

After using dependency injection:

class Car
{
  private Wheel wh   = [Inject an Instance of Wheel at runtime];
  private Battery bt = [Inject an Instance of Battery at runtime];

  Car(Wheel wh,Battery bt) 
  {
      this.wh = wh;
      this.bt = bt;
  }

  //Or we can have setters
  void setWheel(Wheel wh) 
  {
      this.wh = wh;
  }
}

Lets take the below example

public class Foo
{
    private Bar _bar;

    public Foo(Bar bar)
    {
        _bar = bar;
    }

    public bool IsPropertyOfBarValid()
    {
        return _bar.SomeProperty == PropertyEnum.ValidProperty;
    }
}

without dependency injection the Bar object is dependent and tightly coupled with Foo class like below

public class Foo
{
    private Bar _bar = new Bar();
    .
    . 
}

But by using dependency injection like before code you can mock the Bar Object at runtime and call the IsPropertyOfBarValid() method over it.