Pages

Monday, July 26, 2010

SPRING

Introduction to Spring Framework
  • Spring is a open source framework developed by Rod Johnson. Spring is a simplified version of Old J2EE containers.
  • Old J2EE containers provided resource management, life cycle, transaction, security etc services to EJB components. But Spring provides such services to any Java Component (Standalone, web, business or any other components)
  • EJB container runs only on Application server not on command prompt/ web container/ browser. And If dependent objects is required for EJB component. EJB component used to lookup for objects. Where as Spring container says we will inject dependent objects into Java components without any explicit lookup operation.
  • Spring provides integration to every ORM and Web Application frameworks from Spring components in a light weight manner. So that in future if a web application framework wants to change its ORM framework, it provides a simple way of changing the injection of ORM into required web application framework.
Spring Features
Transaction Management: 
  • Spring framework provides a generic abstraction layer for transaction management. This allowing the developer to add the pluggable transaction managers, and making it easy to demarcate transactions without dealing with low-level issues. Spring's transaction support is not tied to J2EE environments and it can be also used in container less environments. 
JDBC Exception Handling: 
  • The JDBC abstraction layer of the Spring offers a meaningful exception hierarchy, which simplifies the error handling strategy
Integration with Hibernate, JDO, and iBATIS: 
  • Spring provides best Integration services with Hibernate, JDO and iBATIS.
AOP Framework: 
  • Spring is best AOP framework
MVC Framework: 
  • Spring comes with MVC web application framework, built on core Spring functionality. This framework is highly configurable via strategy interfaces, and accommodates multiple view technologies like JSP, Velocity, Tiles, iText, and POI. But other frameworks can be easily used instead of Spring MVC Framework.

Spring Architecture
Spring is well-organized architecture consisting of seven modules. Modules in the Spring framework are:



1.Spring AOP
One of the key components of Spring is the AOP framework. AOP is used in Spring:
  • To provide declarative enterprise services, especially as a replacement for EJB declarative services. The most important such service is declarative transaction management, which builds on Spring's transaction abstraction.
  • To allow users to implement custom aspects, complementing their use of OOP with AOP
2.Spring ORM
  • The ORM package is related to the database access. It provides integration layers for popular object-relational mapping APIs, including JDO, Hibernate and iBatis.
3.Spring Web
  • The Spring Web module is part of Spring’s web application development stack, which includes Spring MVC.The Web context module provides basic web-oriented integration features builds on top of the application context module, providing context for Web based applications. As a result, the Spring framework supports integration with Jakartha Struts. The web module also eases the tasks of handling multipart requests and binding request parameters to domain objects
4.Spring DAO
  • The DAO (Data Access Object) support in Spring is primarily for standardizing the data access work using the technologies like JDBC, Hibernate or JDO.
5.Spring Context
  • The Spring context is a configuration file that provides context information to the This package builds on the beans package to add support for message sources and for the Observer design pattern, and the ability for application objects to obtain resources using a consistent API.
6.Spring Web MVC
  • This is the Module which provides the MVC implementations for the web applications. Spring provides a pluggable MVC architecture. The users have a choice to use the web framework or continue to use their existing web framework.Spring separates the roles of the controller; the model object, the dispatcher and the handler object which makes it easier to customize them.Spring web framework is view agnostic and does not push the user to use only JSP's for the view. The user has the flexibility to use JSP's ,XSLT, velocity template etc to provide the view.
7.Spring Core
  • The Core package is the most import component of the Spring Framework.
  • This component provides the Dependency Injection features. The BeanFactory provides a factory pattern which separates the dependencies like initialization, creation and access of the objects from your actual program logic.
Spring IoC
  • Inversion of Control is at the heart of the Spring framework. The basic concept of the Inversion of Control pattern (also known as the Dependent Injection) is that you do not create your objects but describe how they should be created.
  • You don't directly connect your components and services together in code but describe which services are needed by which component in a configuration file.
Spring Containers
In Spring bean instance are managed by Spring container. Spring containers two types:
  • BeanFactory
  • ApplicationContext
BeanFactory
  • As the name implies BeanFactory is an implementation of Factory design pattern.It is a class whose responsibility to create and destroy bean instances.
  • There are several implementations of BeanFactory available in Spring. The most common one is XmlBeanFactory, which reads bean definition from XML document.
BeanFactory factory=new XmlBeanFactory(new FileInputStream("beans.xml"));

ApplicationContext
BeanFactory is fine for simple applicaitons. But to get full advantage of Spring framework you must use Spring advanced container. In addition to BeanFactory , ApplicationContext offers many more features.
  • ApplicationContext can be used to resolve text messages, that means it supports I18N (InternationalizatioN)
  • ApplicationContext provides a facility to load file resources such as Images.
  • ApllicationCDontext can publish events to bean that are generates as listeners.


Application context has three sub classes

1.FileSystemXmlApplicationContext
  •  It is the most commonly used advanced spring container class. It is used to load spring config file (beans.xml/ApplicationContext.xml) exist in the current directory or anywhere in the specified location. That means FileSystemXmlApplicaitonContext class constructor can take local file system/directorey path as an argument.

BeanFactory f = new FileSystemApplicationContext("beans.xml");
ApplicationContext ac = new FileSystemApplicationContext("beans.xml"):

2. ClasspathXmlApplicationContext
Can load XML file placed anywhere in the hard disk provides if the XML file containing directory is included in the Classpath.


3. XmlWebApplicationContext
This is used in web application / .war file to load XML file in servlets, JSP or any other equivalent classes

BeanFactory Life Cycle
A Spring Bean represents a POJO component performing some useful operation. All Spring Beans reside within a Spring Container also known as IOC Container. The Spring Framework is transparent and thereby hides most of the complex infrastructure and the communication that happens between the Spring Container and the Spring Beans. This section lists the sequence of activities that will take place between the time of Bean Instantiation and hand over of the Bean reference to the Client Application.

  1. The Bean Container finds the definition of the Spring Bean in the Configuration file.
  2. The Bean Container creates an instance of the Bean using Java Reflection API.
  3. If any properties are mentioned, then they are also applied. If the property itself is a Bean, then it is resolved and set.
  4. If the Bean class implements the BeanNameAware interface, then the setBeanName() method will be called by passing the name of the Bean.
  5. If the Bean class implements the BeanClassLoaderAware interface, then the method setBeanClassLoader()method will be called by passing an instance of the ClassLoader object that loaded this bean.
  6. If the Bean class implements the BeanFactoryAware interface, then the method setBeanFactory() will be called by passing an instance of BeanFactory object.
  7. If there are any BeanPostProcessors object associated with the BeanFactory that loaded the Bean, then the method postProcessBeforeInitialization() will be called even before the properties for the Bean are set.
  8. If the Bean class implements the InitializingBean interface, then the method afterPropertiesSet() will be called once all the Bean properties defined in the Configuration file are set.
  9. If the Bean definition in the Configuration file contains a 'init-method' attribute, then the value for the attribute will be resolved to a method name in the Bean class and that method will be called.
  10. The postProcessAfterInitialization() method will be called if there are any Bean Post Processors attached for the Bean Factory object.
  11. If the Bean class implements the DisposableBean interface, then the method destroy() will be called when the Application no longer needs the bean reference.
  12. If the Bean definition in the Configuration file contains a 'destroy-method' attribute, then the corresponding method definition in the Bean class will be called.
Life Cycle Phases

4. Bean Name Aware Interface
If the Bean Implementation class wants to know the name of the Bean as configured and maintained by the Bean Factory class, then the Bean class should implement the interface BeanNameAware and override the setBeanName() method. The Bean Factory after reading the Bean definition from the Configuration file will come to know the name of the Bean and will pass this name as an argument to the setBeanName() method.

Person.java

package com.spring;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanNameAware;

public class Person implements BeanNameAware  {

 private String beanName;

 public void setBeanName(String beanName) {
  System.out.println(" <<<<<<<<<<<< 1. BeanNameAware >>>>>>>>>>>>>>");
  this.beanName = beanName;
 }

  public  String getBeanName() {
  return beanName;
 }
}

Main.java

package com.spring;

import  org.springframework.beans.factory.xml.XmlBeanFactory;
import  org.springframework.core.io.ClassPathResource;
import  org.springframework.core.io.Resource;

public class Main {

 /**
  * @param args
  */
 public static void main(String[] args) {

  Resource resource = new ClassPathResource("applicationContext.xml");
  XmlBeanFactory beanFactory = new XmlBeanFactory(resource);
 
  Person person = (Person) beanFactory.getBean("person");
 
  System.out.println(" Bean Name >>> " + person.getBeanName());
}

ApplicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
<bean id="person" class="com.spring.Person">
</bean>
</beans>

Output
 <<<<<<<<<<<< 1. BeanNameAware >>>>>>>>>>>>>>
Bean Name  >>>  person

5. Bean Class Loader Aware Interface
At times, a Client Application may wish to know the details of the Class Loader through which Bean objects are loaded. In such a case, the Bean class should implement the BeanClassLoaderAware interface and override the setBeanClassLoader() method. The Bean Factory object will pass an instance of the ClassLoader object that loaded this Bean to the setBeanClassLoader() method.

Person.java

package com.spring;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanClassLoaderAware;

public class Person implements BeanClassLoaderAware{

 private ClassLoader beanClassLoader;

 public void setBeanClassLoader(ClassLoader classLoader) {
  System.out.println(" <<<<<<<<<<<< 2. BeanClassLoaderAware >>>>>>>>>>>>>>");
  this. beanClassLoader  beanClassLoader ;
 }

  public  String  getBeanClassLoader () {
  return  beanClassLoader ;
 }
}

Main.java

package com.spring;

import  org.springframework.beans.factory.xml.XmlBeanFactory;
import  org.springframework.core.io.ClassPathResource;
import  org.springframework.core.io.Resource;

public class Main {

 /**
  * @param args
  */
 public static void main(String[] args) {

  Resource resource = new ClassPathResource("applicationContext.xml");
  XmlBeanFactory beanFactory = new XmlBeanFactory(resource);
 
  Person person = (Person) beanFactory.getBean("person");
 
  System.out.println(" Bean Class Loader >>> " + person.getBeanClassLoader());
}

ApplicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
<bean id="person" class="com.spring.Person">
</bean>
</beans>

Output
 <<<<<<<<<<<< 2. BeanClassLoader >>>>>>>>>>>>>>
Bean Class Loader >>>   sun.misc.Launcher$AppClassLoader@1813fac

6. Bean Factory Aware Interface
Bean Factory object is responsible for loading and creating Bean instances. This object is sufficient for simple cases. However situations may demand the usage of ApplicationContext and WebApplicationContext for complex scenarios. Both ApplicationContext and WebApplicationContext extend the BeanFactory class and provides advanced configuration such as loading resourcespublishing events etc. So, there must be way for the Spring Bean to know which Bean Factory has actually loaded it. Here comes the BeanFactoryAware interface in which the method setBeanFactory() will be passed an instance of the Bean Factory object that configured and created this Bean.
The Bean Factory object can either be an instance of BeanFactoryApplicationContextWebApplicationContext, etc.

Person.java

package com.spring;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactoryAware;

public class Person implements BeanFactoryAware{

 private BeanFactory beanFactory;

 public void setBeanFactory( BeanFactory beanFactory ) {
  System.out.println(" <<<<<<<<<<<< 3. BeanFactoryAware >>>>>>>>>>>>>>");
  this. beanFactory   beanFactory ;
 }

  public  String  getBeanFactory () {
  return   beanFactory ;
 }
}

Main.java

package com.spring;

import  org.springframework.beans.factory.xml.XmlBeanFactory;
import  org.springframework.core.io.ClassPathResource;
import  org.springframework.core.io.Resource;

public class Main {

 /**
  * @param args
  */
 public static void main(String[] args) {

  Resource resource = new ClassPathResource("applicationContext.xml");
  XmlBeanFactory beanFactory = new XmlBeanFactory(resource);
 
  Person person = (Person) beanFactory.getBean("person");
 
  System.out.println(" Bean Factory  >>> " + person.getBeanFactory());
}

ApplicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
<bean id="person" class="com.spring.Person">
</bean>
</beans>

Output
 <<<<<<<<<<<< 3. BeanFactoryAware >>>>>>>>>>>>>>
Bean Factory >>>   org.springframework.beans.factory.xml.XmlBeanFactory@13787ba: defining beans [person]; root of factory hierarchy

7. Bean Post Processors Interface
Customization of Bean instances in an Application can happen for variety of reasons. For example, once a Bean object is created, various other data from a legacy system has to be populated on the Bean object. It may not be possible to configure the legacy data information in the Configuration file.We have defined one Bean Post Processor class for customizing the behavior for some set of Beans with common nature. The method postProcessBeforeInitialization() will be called even before the properties for the Bean are set. And the method postProcessAfterInitialization() will be called after the properties for the Bean object are set.

Person.java

package com.spring;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactoryAware;

public class Person implements BeanNameAware,BeanClassLoaderAware,BeanFactoryAware,InitializingBean,DisposableBean{

 private String beanName;
 private ClassLoader beanClassLoader;
 private BeanFactory beanFactory;

 public void setBeanName(String beanName) {
  System.out.println(" <<<<<<<<<<<< 1. BeanNameAware >>>>>>>>>>>>>>");
  this.beanName = beanName;
 }

  public  String getBeanName() {
  return beanName;
 }

 public void setBeanClassLoader(ClassLoader classLoader) {
  System.out.println(" <<<<<<<<<<<< 2. BeanClassLoaderAware >>>>>>>>>>>>>>");
  this. beanClassLoader  beanClassLoader ;
 }

  public  String  getBeanClassLoader () {
  return  beanClassLoader ;
 }

 public void setBeanFactory( BeanFactory beanFactory ) {
  System.out.println(" <<<<<<<<<<<< 3. BeanFactoryAware >>>>>>>>>>>>>>");
  this. beanFactory   beanFactory ;
 }

  public  String  getBeanFactory () {
  return   beanFactory ;
 }
    public   void afterPropertiesSet() throws Exception {
            if (name == null)
        {
            throw new Exception("Name field not set.");
        }else{
            System.out.println(" <<<<<<<<<<<< 5. InitializingBean >>>>>>>>>>>>>>"+ name);
        }
      }

    public   void destroy() throws Exception {
         this.name = null;
         System.out.println(" <<<<<<<<<<<< 7. DisposableBean >>>>>>>>>>>>>>"+ name);
            }

}

ControllerPostProcessor.java
package com .spring;

import  org.springframework.beans.BeansException;
import  org.springframework.beans.factory.config.BeanPostProcessor;

public   class PersonPostProcessor  implements  BeanPostProcessor {

  public Object postProcessBeforeInitialization(Object bean, String beanName)
                                     throws  BeansException {
       System.out.println(" <<<<<<<<<<<< 4. BeanPostProcessor - postProcessBeforeInitialization >>>>>>>>>>>>>>");
                       
              return   bean;
            }

             public  Object postProcessAfterInitialization(Object bean, String beanName)
                                     throws   BeansException {
              System .out.println(" <<<<<<<<<<<< 6. BeanPostProcessor - postProcessAfterInitialization >>>>>>>>>>>>>>");
                         return    bean;
            }

}

The above client code registers the custom Bean Post Processor to the Bean Factory object by calling the method BeanFactory.addBeanPostProcessor(). It is possible to add any number of Bean Post Processor objects.

Main.java

package com.spring;

import  org.springframework.beans.factory.xml.XmlBeanFactory;
import  org.springframework.core.io.ClassPathResource;
import  org.springframework.core.io.Resource;

public class Main {

 /**
  * @param args
  */
 public static void main(String[] args) {

  Resource resource = new ClassPathResource("applicationContext.xml");
  XmlBeanFactory beanFactory = new XmlBeanFactory(resource);
 
 PersonPostProcessor beanPostProcessor =  new  PersonPostProcessor();
 beanFactory.addBeanPostProcessor(beanPostProcessor);

  Person person = (Person) beanFactory.getBean("person");
  beanFactory.destroySingleton("person");

}

ApplicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
<bean id="person" class="com.spring.Person">
</bean>
</beans>

Output
 <<<<<<<<<<<< 1. BeanNameAware >>>>>>>>>>>>>>
 <<<<<<<<<<<< 2. BeanClassLoaderAware >>>>>>>>>>>>>>
 <<<<<<<<<<<< 3. BeanFactoryAware >>>>>>>>>>>>>>
 <<<<<<<<<<<< 4. BeanPostProcesser - postProcessBeforeInitialization>>>>>>>>>>>>>>
 <<<<<<<<<<<< 5. InitializingBean >>>>>>>>>>>>>>
 <<<<<<<<<<<< 6. BeanPostProcesser - postProcessAfterInitialization>>>>>>>>>>>>>>
<<<<<<<<<<<< 7. DisposableBean >>>>>>>>>>>>>>

8. Initializing Bean
The InitializingBean interface may be implemented by Bean class who wish to do some post processing actions when all the properties have been set.
the bean instance is created, this method also will be called.
Spring’s managed bean has to implement InitializingBean from the springframework. This interface declares one method afterPropertiesSet() which has to be overridden by the bean. So, when the bean instance is created, this method also will be called.
Though this technique is not recommended. It is easy to directly configure in the xml configuration file with the initialization method name.use init-method=”initialize” to set the value. Look into the following code for more details on implementation.

Person.java
package com.spring;

import org.springframework.beans.factory.InitializingBean;

public class Person implements InitializingBean{

 private String beanName;

public void setBeanName(String beanName) {
  System.out.println(" <<<<<<<<<<<< 1. BeanNameAware >>>>>>>>>>>>>>");
  this.beanName = beanName;
 }

public  String getBeanName() {
  return beanName;
 }

public   void afterPropertiesSet() throws Exception {
   if (name == null)
        {
            throw new Exception("Name field not set.");
        }else{
            System.out.println(" <<<<<<<<<<<< 5. InitializingBean >>>>>>>>>>>>>>"+ name);
        }
      }

}




Main.java

package com.spring;

import  org.springframework.beans.factory.xml.XmlBeanFactory;
import  org.springframework.core.io.ClassPathResource;
import  org.springframework.core.io.Resource;

public class Main {

 /**
  * @param args
  */
 public static void main(String[] args) {

  Resource resource = new ClassPathResource("applicationContext.xml");
  XmlBeanFactory beanFactory = new XmlBeanFactory(resource);

  Person person = (Person) beanFactory.getBean("person");
}

ApplicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
<bean id="person" class="com.spring.Person">
</bean>
</beans>

Output
 <<<<<<<<<<<< 5. InitializingBean >>>>>>>>>>>>>>


Spring Modules and corresponding Jar Files
The Spring Project is not a single project but it comes in flavor of Several Modules. A module can be defined or thought of a functionality that is very specific to an area. Spring Distribution comes in several such modules. The name of the Spring module along with the jar file name (which is available in the SPRING_HOME\dist\modules) is listed below.


  • Spring Web MVC (spring-webmvc.jar)
  • Spring Aop (spring-aop.jar)
  • Spring Beans (spring-beans.jar)
  • Spring Context (spring-context.jar)
  • Spring Core (spring-core.jar)
  • Spring Dao (spring-dao.jar)
  • Spring Hibernate (spring-hibernate3.jar)
  • Spring Ibatis (spring-ibatis.jar)
  • Spring Jca (spring-jca.jar)
  • Spring Jdbc (spring-jdbc.jar)
  • Spring Jdo (spring-jdo.jar)
  • Spring Jms (spring-jms.jar)
  • Spring Jms (spring-jpa.jar)
  • Spring Jmx (spring-jmx.jar)
  • Spring Portlet (spring-portlet.jar)
  • Spring Remoting (spring-remoting.jar)
  • Spring Struts (spring-struts.jar)
  • Spring Support (spring-support.jar)
  • Spring Toplink (spring-toplink.jar)
  • Spring Web (spring-web.jar)
  • Spring Aspects (spring-aspects.jar)

Every module in the above list has their own functionality as identified by the name of the Jar File. For example,Spring Jmx (spring-jmx.jar) provides Instrumentation and Management Support to Spring Bean components. Similarly, Spring Web provides developing Web Application Infrastructure for the Server side. Since all the pieces of functionality are made well modular and they come as a separate functionality (via a Jar File), say, if an Applicationwants to take functionality of Aspect Oriented programming (spring- aspects.jar) and Database Access (spring-jdbc.jar), it can include any two of these jar Files in its classpath. But, what will happen if an Application is in need of the functionality provided by all the various modules. Should it define entries for all the Jar Files in its class-path? Spring provides a smart solution for this need, as it comes with a Jar File called spring.jar which is a combination of all the modules.







No comments:

Post a Comment