In the Spring Container the underlying persistence unit(oracle, mysql) used can be conveyed in three ways

  1. Dialect
  2. Vendor
  3. Provider

Using Dialect in Spring(or)application.xml

<bean id="jpaDialect" class="org.springframework.orm.jpa.vendor.HibernateJpaDialect"/>

<bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
    </property>
....
</bean>

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="emf"/>
    <property name="jpaDialect" ref="jpaDialect"/>
</bean>

We are telling ‘Spring’ to configure a transactionManager whose properties are entityManagerFactory and jpaDialect. Since these properties have to be specific to hibernate these are set according. The entityManagerFactory and jpaDialect are now set specifically to hibernate (or Vendor).

Dialect and Vendor Adapter works together

Notes:

  1. transactionManager needs entityManagerFactory and jpaDialect
  2. entityManagerFactory – defines database related properties
  3. jpaDialect – JpaDialect is an interface encapsulates certain functionality that standard JPA 1.0 does not offer, such as access to the underlying JDBC Connection.

Using Vendor in Spring(or)application.xml

<property name="jpaVendorAdapter">
    <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
</property>

the VendorAdapter is injected in to transactionManager along with entityManager
Since you have provided the class as class=”org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter”/>, this allows Spring to plug in vendor-specific behavior into Spring’s EntityManagerFactory creators and it serves as single configuration point for all vendor-specific properties.It’s a custom implementation of spring’s own JpaVendorAdapter.

The reason it is so is the underlying database differs from application to application based on the needs and the underlying persistence unit which the developer would like to use I.E MySQL, Oracle.

Using Provider persistence-context.xml

org.hibernate.ejb.HibernatePersistence [/xml]

The tells spring to use the hibernate provider and the class org.hibernate.ejb.HibernatePersistence is Hibernate EJB3 persistence provider implementation.

Note:
Application works just by configuring persistence and provider because the vendor adapter is automatically passed by the persistence provided i.e. HibernatePersistence via the getPersistenceProvider in JpaVendorAdapter.

Provider + JpaVendorAdapter(Used getPersistenceProvider to get underlying Persistence technology in our case hibernate) -> Works
Dialect + JpaVendorAdapter -> Works
Provider + Dialect -> Doesn’t Works

Difference between configuring data source in persistence.xml and spring (or) application-context.xml files

persistence-context.xml

<persistence-unit name="LocalDB" transaction-type="RESOURCE_LOCAL">
    <class>domain.User</class>
    <exclude-unlisted-classes>true</exclude-unlisted-classes>
    <properties>
        <property name="hibernate.connection.driver_class" value="org.hsqldb.jdbcDriver"/>
        <property name="hibernate.connection.url" value="jdbc:hsqldb:hsql://localhost"/>
        <property name="hibernate.hbm2ddl.auto" value="create"/>
        <property name="hibernate.c3p0.min_size" value="5"/>
        ....
        <property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/>
    </properties>
</persistence-unit>

application-context.xml

<bean id="domainEntityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="persistenceUnitName" value="JiraManager"/>
    <property name="dataSource" ref="domainDataSource"/>
    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
            <property name="generateDdl" value="false"/>
            <property name="showSql" value="false"/>
            <property name="databasePlatform" value="${hibernate.dialect}"/>
        </bean>
    </property>
</bean>

<bean id="domainDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
    <property name="driverClass" value="${db.driver}" />
    <property name="jdbcUrl" value="${datasource.url}" />
    <property name="user" value="${datasource.username}" />
    <property name="password" value="${datasource.password}" />
    <property name="initialPoolSize" value="5"/>
    <property name="minPoolSize" value="5"/>
    .....
</bean>

If you are using persistence.xml you’re creating your own connection pool and do not profit from the existing connection pool in the container. Thus even if you configured your container to, say, a max of 20 simultaneous connections to the database, you can’t guarantee this max as this new connection pool is not restrained by your configuration. Also, you don’t profit from any monitoring tools your container provides you.

If you are using spring (or) application.xml
If you’re also creating your own connection pool, with the same disadvantages as above. However, you can isolate the definition of this spring bean and only use it in test runs.Your best bet is to look up the container’s connection pool via JNDI. Then you are sure to respect the data source configurations from the container.

application-context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:p="http://www.springframework.org/schema/p"
  xmlns:context="http://www.springframework.org/schema/context"
  xmlns:tx="http://www.springframework.org/schema/tx"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:aop="http://www.springframework.org/schema/aop"
  xmlns:jdbc="http://www.springframework.org/schema/jdbc"
  xsi:schemaLocation="
   http://www.springframework.org/schema/beans
   http://www.springframework.org/schema/beans/spring-beans.xsd
   http://www.springframework.org/schema/aop
   http://www.springframework.org/schema/aop/spring-aop.xsd
   http://www.springframework.org/schema/tx
   http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
   http://www.springframework.org/schema/jdbc
   http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd
   http://www.springframework.org/schema/context
   http://www.springframework.org/schema/context/spring-context-3.0.xsd">  
   
<context:component-scan base-package="mugil.org.*" />      
<tx:annotation-driven transaction-manager="transactionManager"/>
  
<bean id="transactionManager"
  class="org.springframework.orm.jpa.JpaTransactionManager">
     <property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>

<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
p:dataSource-ref="dataSource" p:persistenceUnitName="simple-jpa">
 </bean>
  
 <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/MUSIC_STORE"/>
        <property name="username" value="music_store"/>
        <property name="password" value="music_store"/>  
 </bean>     
</beans>

Dissection of application-context.xml

 <context:component-scan base-package="mugil.org.*" />
  1. This component-scan tag also enables the usage of JPA annotations.
  2. Enables the usage of JPA annotations(@Service, @Component, @Repository, @Controller and etc.,)
  3. annotation-config —> enables the usage of JPA annotations , only in the beans specified in the context.xml whereas (ii) component-scan —> scans through all the packages specified, records all the project beans having JPA annotations, into this context.xml. Therefore it enables JPA annotaion usage in (beans specified in context.xml)+(Project Beans).Inshort, component-scan extends annotation-config.

Note:
When we use component-scan in the app-context.xml, it’s not necessary to use annotation-config again.Even if both the tags are specified, it’s not a problem because, the spring container would take care of running the process only once.

 <tx:annotation-driven transaction-manager="transactionManager"/>
  1. It checks for @Transactional annotation in any of the classes. This tag is like a Transactional Switch that turns on the transactional behaviour.Here Transaction Manager is being injected
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
   <property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>

 <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/MUSIC_STORE"/>
        <property name="username" value="music_store"/>
        <property name="password" value="music_store"/>  
 </bean>     
  1. Here Transaction Manager is setup.EntityManagerFactory is being injected.
  2. Here EntityManagerFactory is setup .Data Source reference and Persistence UnitName Reference is specified.
  3. DB connection details are specified.
  4. Based on the PersistenceUnit name, the corresponding portion of persistence.xml is accessed (a Project can have multiple persistenceUnitNames)

persistence-context.xml

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
             xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
  <persistence-unit name="simple-jpa" transaction-type="RESOURCE_LOCAL">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <class>mugil.pojo.MusicDetails</class>
    <exclude-unlisted-classes>true</exclude-unlisted-classes>
    <properties>
      <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/> 
      <property name="hibernate.show_sql" value="true"/>
      <property name="hibernate.max_fetch_depth" value="3"/> 
    </properties>
  </persistence-unit>
</persistence>

Dissection of persistence-context.xml

  1. persistence-unit – Defines the Name of the Persistence Unit
  2. provider – ORM tool by which the underlying persistence would be accessed
  3. class – Entity Class Names
  4. properties – Defining the underlying persistence technology and other properties would be configured here

Other Java Codes
DaoInterface.java

public interface IMusicStoreDao 
{
   public List getMusicList();
}

DaoImplementation.java

@Service(value = "MusicCollections")
@Repository(value = "MusicCollections")
@Transactional
public class MusicStoreDaoImpl implements IMusicStoreDao{
 
  @PersistenceContext(unitName = "simple-jpa")
    private EntityManager entityManager;
 
   @Override
     public List getMusicList(){
     List musicDetailsList= entityManager.createQuery("select c from MusicDetails c").getResultList();
     return musicDetailsList;
    }
}

Executer.java

public class Executer {
   public static void main(String[] args){
        ApplicationContext applicationContext=new ClassPathXmlApplicationContext("META-INF/app-context.xml");
        IMusicStoreDao musicStoreDao=(IMusicStoreDao) applicationContext.getBean("MusicCollections");
        System.out.println("MusicList: \n"+musicStoreDao.getMusicList());
    }
}

Reference:
Spring and JPA

Posted in JPA.

In a Application the persistence unit used to store the data may vary.Accessing data varies depending on the source of the data. Access to persistent data varies greatly depending on the type of storage (database, flat files, xml files, and so on) and it even differs from its implementation (for example different SQL-dialects).

The advantage of the DAO layer is that if you need to change the underlying persistence mechanism you only have to change the DAO layer, and not all the places in the domain logic where the DAO layer is used from. The DAO layer usually consists of a smaller set of classes, than the number of domain logic classes that uses it.

Abstract and encapsulate all access to the data and provide an interface. This is called the Data Access Object pattern. In a nutshell, the DAO “knows” which data source (that could be a database, a flat file or even a WebService) to connect to and is specific for this data source (e.g. a OracleDAO might use oracle-specific data types, a WebServiceDAO might parse the incoming and outgoing message etc.)

BookDAO.java

public interface BookDAO {
  public void saveBook(Book b);
  public Book loadBook(String isbn);
}

DBBookDAO.java

public class DBBookDAO implements BookDAO {

  private PreparedStatement saveStmt;
  private PreparedStatement loadStmt;

  public DBBookDAO(String url, String user, String pw) {
    Connection con = DriverManager.getConnection(url, user, pw);
    saveStmt = con.prepareStatement("INSERT INTO books(isbn, title, author) "
                                   +"VALUES (?, ?, ?)");
    loadStmt = con.prepareStatement("SELECT isbn, title, author FROM books "
                                   +"WHERE isbn = ?");
  }

  public Book loadBook(String isbn) {
    Book b = new Book();
    loadStmt.setString(1, isbn);
    ResultSet result = loadStmt.executeQuery();
    if (!result.next()) return null;
    
    b.setIsbn(result.getString("isbn"));
    b.setTitle(result.getString("title"));
    b.setAuthor(result.getString("author"));
    return b;
  }

  public void saveBook(Book b) {
    saveStmt.setString(1, b.getIsbn());
    saveStmt.setString(2, b.getTitle());
    saveStmt.setString(3, b.getAuthor());
    saveStmt.executeUpdate();
  }
}

FileBookDAO.java

public class FileBookDAO implements BookDAO {
        
  private String basePath;

  public FileBookDAO(String basePath) {
    this.basePath = basePath;
  }

  public Book loadBook(String isbn) {
    FileReader fr = new FileReader(basePath + isbn);
    BufferedReader br = new BufferedReader(fr);
    Book b = new Book();
    String rIsbn = br.readLine();
    String rTitle = br.readLine();
    String rAuthor = br.readLine();
        
    if (rIsbn.startsWith("ISBN: ")) {
      b.setIsbn(rIsbn.substring("ISBN: ".length()));
    } else {
      return null;
    }
    if (rTitle.startsWith("TITLE: ")) {
      b.setTitle(rTitle.substring("TITLE: ".length()));
    } else {
      return null;
    }
    if (rAuthor.startsWith("AUTHOR: ")) {
      b.setAuthor(rAuthor.substring("AUTHOR: ".length()));
    } else {
      return null;
    }
    return b;
  }

  public void saveBook(Book b) {
    FileWriter fw = new FileWriter(basePath + b.getIsbn() + ".book");
    fw.write("ISBN: " + b.getIsbn());
    fw.write("TITLE: " + b.getTitle());
    fw.write("AUTHOR: " + b.getAuthor());
    fw.close();
  }
}
  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 Template Pattern?
Template pattern, an abstract class exposes a ways to execute its methods. The subclasses can override the method implementation as per need but the invocation is to be in the same way as defined by an abstract class

When to use Template Pattern?

  1. When behaviour of an algorithm can vary, you let subclasses implement the behaviour through overriding
  2. You want to avoid code duplication, implementing variations of the algorithm in subclasses
  3. You want to control the point that subclassing is allowed.

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.