Spring 1.What is Spring Framework • • • •
Spring is a lightweight open source framework written by Rod Johnson in 2000 Light-weight yet comprehensive framework for building Java SE and Java EE applications. Spring Framework is a Java platform that provides comprehensive infrastructure support for developing Java applications. An open-source layered Java/J2EE application framework having a light-weight container implementing Inversion-of-Control and Aspect Oriented Programming.
2.History of Spring Framework
• • • • •
The first version was written by Rod Johnson who released the framework with the publication of his book Expert One-on-One J2EE Design and Development in October 2002 The framework was first released under the Apache 2.0 license in June 2003 The first milestone release, 1.0, was released in March 2004, with further milestone releases in September 2004 and March 2005 Spring 2.0 was released in October 2006, and Spring 2.5 in November 2007 In January 2009 version 3.0 was released. The current version is 3.0.5 The below diagram shows past releases:
3.Why Spring Framework •
It addresses important areas that many other popular frameworks don't.
• •
Spring focuses around providing a way to manage our business objects
• •
Spring is both comprehensive and modular: Spring has a layered architecture, meaning that we can choose to use just about any part of it in isolation, yet its architecture is internally consistent Spring is designed from the ground up to help we write code that's easy to test. Spring is an ideal framework for test driven projects. Spring is an increasingly important integration technology, its role recognized by several large vendors.
4.Introduction to Spring Framework • •
•
Spring Framework is a Java platform that provides comprehensive infrastructure support for developing Java applications. Spring handles the infrastructure so we can focus on our application. Spring enables us to build applications from “plain old Java objects” (POJOs) and to apply enterprise services non-invasively to POJOs. This capability applies to the Java SE programming model and to full and partial Java EE. Spring is useful when •
we have objects whose implementations change often
•
These objects are defined in bean definition file,isolating Java code from changes in the implementation
•
we supply initialization values via constructors or setters
4.1.Spring 3.0 Architecture The Spring Framework consists of features organized into about 20 modules. These modules are grouped into: Core Container Data Access/Integration Web AOP (Aspect Oriented Programming) Instrumentation Test Following diagram shows all the modules of the spring framework:
Following diagram shows basic modules of the spring framework:
4.1.1 Core Container ( Spring IOC ) The IOC container is the main component of the Spring framework. It provides the main IoC container and AOP framework The core container of the Spring Framework provides important functionality including dependency injection and bean life-cycle management The core container is responsible for providing essential functionality to the Spring framework
The core container of the Spring Framework provides Dependency Injection and Inversion of Control (IOC) functionalities Inversion of Control is best understood through the term the “Hollywood Principle,” which basically means “Don’t call me, I’ll call you.”
•
Dependency Injection and Inversion of Control ( IOC ):
The aspect of IoC that the Spring Framework uses is "Injection of required resources or dependency at Run-time into the dependent resource," which is also known as Dependency Injection.
Hence, the service provided by the IoC container of Spring is Dependency Injection. Therefore, we will be using the terms IoC and Dependency Injection in a lax way Developers uses the IoC container to manage the beans and its dependency in the application. That means spring IOC container manages one or more beans.
Beans are created using the instructions defined in the configuration metadata that has been supplied to the container in the form of XML <bean/> definitions. The container will creates all the objects , connects them together by setting the necessary properties and determines when methods will be invoked. The dependency injection is about building relationships of the objects. The dependencies can be of primitive types or other objects. Spring support two types of dependency injection:
•
Constructor Injection - The dependency is injected via constructor arguments.
•
Setter Injection - Dependency is provided through setter methods as per Java Bean style.
The below diagram shows types of dependency injection:
•
Constructor Injection
• • •
Constructor-based DI is realized by invoking a constructor with a number of arguments, each representing a collaborator. Here the IoC container injects the dependency through the constuctor. Let's have a constructor in User which has arguments
User.java public class User {
}
User(String first,String last){ firstName =first; lastName = last; }
Now to inject the dependencies, put the dependencies via configuration XML <bean id=“user” class=“User”> <constructor-arg value=“user_first_name"/> <constructor-arg value=“user_last_name"/> </bean> Suppose we have a constructor User(int,double) than we can use <bean id=“user” class=“User”> <constructor-arg type="int" value="45" /> <constructor-arg type="double" value="58.5" /> </bean> If suppose we have two constructors User(String) and User(int) and have the following in XML <bean id=“user” class=“User”> <constructor-arg value="45" /> </bean> Spring will go for User(String), as there is no way for it figure out that the value is a number. In XML everything is String. However if we want to use User(int) then qualify it with type. •
Setter Injection
• • •
Using setter methods in a bean class the Spring IOC container will inject the dependencies. This technique is considered as the best approach for Dependency Injection. In this type of injection we have chance to reconfigure the bean instance as needed basis.
Example: Employee.java public class Employee { private String name; private String empId; private Address address; public Employee(){ } public Address getAddress() { return address; } public void setAddress(Address address) { this.address = address; } public String getEmpId() { return empId; } public void setEmpId(String empId) { this.empId = empId; } public String getName() { return name; } public void setName(String name) { this.name = name; } } Address.java public class Address { public Address(){ } private String street; private String city; public String getCity() { return city; } public void setCity(String city) { this.city = city; } public String getStreet() { return street; } public void setStreet(String street) { this.street = street; }
applicationContext.xml <bean id="addressBean" class="com.clickandbuy.spring.ioc.Address"> <property name="street"> <value>Street</value> </property> <property name="city"> <value>Hyderabad</value> </property> </bean> <bean id="employeeBean" class="com.clickandbuy.spring.ioc.Employee"> <property name="name" value="emp_name"/> <property name="empId" value="emp_id"/> <property name="address" ref="addressBean"/> </bean>
Figure below illustrates the process by which a bean container creates two beans from configuration instructions, and injects a dependency between the two beans
employeeBean
creation
addressBean
Dependency Injection
creation
Bean Container
XML Config
Following are the modules of Core Container: • • • •
Beans Core Context Expression Language
Beans,BeanFactory and Application Context • • • • • • •
•
Beans A spring bean represents a POJO component. Objects that form backbone of our application and that are managed by the spring Ioc container are referred to as beans. A bean is simply an object that is instantiated,assembled and otherwise managed by a spring IoC Container. Spring beans exist within the container as long as they are needed by the application. The basic package in the spring framework is the org.springframework.beans package. This package provides most of the basic functionality to manipulate Java beans and provides the basic infrastructure for the other spring framework classes. Within the container itself ,bean definitions are represented as BeanDefinition objects,which contain the following metadata: • a package-qualified class name –this is normally actual implementation class of the bean described in bean definition • bean behavioral configuration elements - which state how the bean should behave in the container (i.e. prototype or singleton, autowiring mode, dependency checking mode, initialization and destruction methods) • constructor arguments and property values - to set in the newly created bean. • other beans – which are needed for the bean to do its work,that is collaborators ( also called dependencies). • The concepts listed above directly translate to a set of elements the bean definition consists of. Some of these element groups are listed below: • id and name : These are the bean identifiers. Every bean has one or more ids • class : specifies the class of the bean to be constructed • Bean Properties • Bean Scope • Constructor arguments • autowiring mode • dependency checking mode • lazy-initialization mode • initialization method • destruction method
•
Syntax
<beans> <bean id=”bean-id” name=”bean-name” class=”full-path of class name”/> <bean id=”bean-id” name=”bean-name” class=”full-path of class name”> <constructor-arg></constructor-arg> <constructor-arg></construcor-arg> </bean> </beans>
• •
Here Namespace beans provides the elements used in the definition of beans. The below table shows available XML tags or elements and its attributes.
Tag
Attributes
<beans>
Sub-tags
Description
<bean>
Top-level element
<bean>
Id | name | scope| ...
<property | constructor-arg>
Define bean
<property>
name | value | ref
<list | set | map>
Define property value
<constructor-arg> Value | ref | type | index
<list | set | map>
Define constructor
<list>
merge
<value | ref>
Define List collection value
<set>
merge
<value | ref>
Define Set collection value
<ref>
bean local parent
bean reference value
<value>
value
simple or rich value
<idref>
bean local parent
bean name value
<map>
merge
<value | ref>
Define Map collection value
<entry>
key value value-ref
<key|value>
map entry
<key>
key for map entry
<props>
merge
<prop>
key
<null>
•
<prop>
Define Properties value Define property value Null value
Instantiating Beans • Spring will instantiate a bean from the given metadata in XML file. • There are two ways to instantiate the bean • Using constructor • Using static factory method • Using instance factory method • Instantiation using a Constructor • When creating a bean using the constructor approach, all normal classes are usable by and compatible with Spring. • That is, the class being created does not need to implement any specific interfaces or be coded in a specific fashion. • Example:
<bean id="emailService" class="com.clickandbuy.EmailService"> <constructor-arg>name</constructor-arg> <constructor-arg>subject</construcor-arg> </bean> //Empty Constructor <bean name=”smsService class=”com.clickandbuy.SmsService”/> •
Instantiation using a static Factory method • When defining a bean which is to be created using a static factory method, along with the class attribute which specifies the class containing the static factory method, another attribute named factory-method is needed to specify the name of the factory method itself. • Example:
<bean name=”smsService class=”com.clickandbuy.SmsService” factory-method=”createInstance”/> Here bean is created by calling a factory-method and createInstance() method must be a static method. • Instantiation using an instance Factory Method • In a fashion similar to instantiation via a static factory method . • Instantiation using an instance factory method is where the factory method of an existing bean from the container is invoked to create the new bean. • Example: <bean name=”smsService class=”com.clickandbuy.SmsService” factory-bean=”myFactoryBean” factory-method=”createInstance”/> <bean id=”myFactoryBean” class=”...”> ... </bean> To use this mechanism,the 'class' attribute must be left empty and the 'factory-bean' attribute must specify the name of a bean in the current (or parent/ancestor) container that contains the factory method. The factory method itself must still be set via the 'factorymethod' attribute. •
•
Bean Scopes Spring Framework supports exactly five scopes. User can control the scope of the objects created from a particular bean definition . • Singleton • Prototype • Request • Session • Global Session Singleton: • The singleton return a single bean instance per spring IoC container • This scope is available for both BeanFactory and ApplicationContext • when we define a bean definition and it is scoped as a singleton, then the Spring IoC container will create exactly one instance of the object defined by that bean definition. • This single instance will be stored in a cache of such singleton beans, and all subsequent requests and references for that named bean will result in the cached object being returned. • singleton scope is the default scope. • singleton attribute really makes Spring do is to cache and always return the same bean instance for all the requests on this bean • Example:
<bean id="emailService" class="com.clickandbuy.EmailService"/> <!-- the following is equivalent, singleton scope is the default scope. --> <bean id="emailService" class="com.clickandbuy.EmailService" scope="singleton"/> <!-- the following is equivalent --> <bean id="emailService" class="com.clickandbuy.EmailService" singleton="true"/>
•
•
Benefits: • Reduced configuration and less code (inject once use everywhere) • Injected Singletons can be used in classes that are not part of the beanwiring chain • Static methods can use injected Singletons • Injected Singletons can serve as beanwiring starting points • Increased productivity (instant usage of injected code) Prototype: • The prototype return a new bean instance each time when requested. • Scopes a single bean definition to any number of object instances. • Allows a bean to be instantiated any number of times but bean is initialized once for the user. • This scope available for both BeanFactory and ApplicationContext. • Create a new bean instance every time a request for that specific bean is made ( is injected into another bean or it is requested via a programmatic getBean() method call on the container) • Example:
<!-- create new instance every on request. --> <bean id="emailService" class="com.clickandbuy.EmailService" scope="prototype"/> <!-- the following is equivalent --> <bean id="emailService" class="com.clickandbuy.EmailService" singleton="false"/>
•
Request: • Scopes a single bean definition to the life cycle of a single HTTP request; that is each and every HTTP request will have its own instance of a bean created off the back of a single bean definition. • Only valid in the context of a web-aware Spring ApplicationContext like XmlWebApplicationContext. • Example:
<bean id="emailService" class="com.clickandbuy.EmailService" scope="request"/> •
Session: • Scopes a single bean definition to the lifecycle of a HTTP Session. • Only valid in the context of a web-aware Spring ApplicationContext like XmlWebApplicationContext. • Example:
<bean id="emailService" class="com.clickandbuy.EmailService" scope="session"/> •
Global Session: • Scopes a single bean definition to the lifecycle of a gloabal HTTP Session. • Typically only valid when used in a portlet context. Only valid in the context of a web-aware Spring ApplicationContext like XmlWebApplicationContext • Example:
<bean id="emailService" class="com.clickandbuy.EmailService" scope="globalSession"/> •
Checking for dependencies • Spring has the ability to try to check for the existence of unresolved dependencies of a bean deployed into the BeanFactory. • These are JavaBeans properties of the bean, which do not have actual values set for them in the bean definition, or alternately provided automatically by the autowiring feature.
•
• •
Mode
This feature is sometimes useful when we want to ensure that all properties (or all properties of a certain type) are set on a bean. Of course, in many cases a bean class will have default values for many properties, or some properties do not apply to all usage scenarios, so this feature is of limited use. Dependency checking can also be enabled and disabled per bean, just as with the autowiring functionality. The default is to not check dependencies. Dependency checking can be handled in several different modes. In an XmlBeanFactory, this is specified via the dependency-check attribute in a bean definition, which may have the following values. Explanation
None
No dependency checking. Properties of the bean which have no value specified for them are simply not set.
Simple
Dependency checking is performed for primitive types and collections (everything except collaborators, that is other beans)
object
Dependency checking is performed for collaborators
all
Dependency checking is done for collaborators, primitive types and collections •
Lazy-initialization in Spring IOC • As we know Spring's bean factory is per-initiate all the beans when first time creating the factory. This is good practice because if there is any dependency error everything can be resolved at the time of startup. This is not case in all the application scenarios. • The following are the few drawbacks in per-initiating all the beans at startup: • Takes long time to start the application. Since BeanFactory has to initiate all the beans even if it is unnecessary. • More memory for storing all the beans. • Based on the above impacts, some applications required beans to initiate only when they are required. Spring provides an attribute called lazy-init to inform the Spring IOC container for not creating that bean at the startup. lazy-init will be set as true to indicate the container. The beans will be created only when requested. • Consider when there is a bean which is initiated at the startup. But, it has dependson attribute pointing to the bean which is set as lazy-init="true". This case the can will be initiated without considering lazy-init value. • When configuring beans via XML, this lazy loading is controlled by the 'lazy-init' attribute on the <bean/> element; for example: • Example:
<bean id="lazy" class="com.clickandbuy.EmailService" lazy-init=”true”/> When the above configuration is consumed by an ApplicationContext, the bean named 'lazy' will not be eagerly per-instantiated when the ApplicationContext is starting up. It is also possible to control lazy-initialization at the container level by using the 'default-lazy-init' attribute on the <beans/> element; for example: <beans default-lazy-init=”true”> <!-- no beans will be per-instantiated... - - > </beans>
•
Autowiring collaborators • Spring have many collaborating bean, the autowire help in making the relationship between them. • Autowiring reduces the effort of writing properties or constructor arguments. The autowiring in specified at the autowire attribute inside <bean/> element. The functionality of autowiring seen in five mode.
Mode
Explanation
no
It is default which define no autowiring.
byName
Autowiring is done by property name. Attempts to find a bean in the container whose name (or ID) is the same as the name of the property being wired. If a matching bean is not found, the property will remain unwired.
byType
Autowiring is done by matching data type of property name. Attempts to find a single bean in the container whose type matches the type of the property being wired. If no matching bean is found, the property will not be wired. If more than one bean matches, an org.springframework.beans.factory.UnsatisfiedDependencyException
constructor Autowiring is done by matching data type of property name with the property constructor argument. Tries to match up one or more beans in the container with the parameters of one of the constructors of the bean being wired. In the event of ambiguous beans or ambiguous constructors, an org.springframework.beans.factory.UnsatisfiedDependencyException will be thrown. autodetect When default constructor with no argument, it auto-wire by data type or it autowire by constructor. Attempts to autowire by constructor first and then using byType. Ambiguity is handled the same way as with constructor and byType wiring. • Usage: <beans> <bean <bean <bean <bean <bean <bean </beans>
id="a" class="A"/> id="b" class="B"/> id="byName" autowire="byName" class="MyClass"/> id="byType" autowire="byType" class="MyClass"/> id="constructor" autowire="constructor" class="MyClass"/> id="autodetect" autowire="autodetect" class="MyClass"/>
• Bean Life-cycle: Spring's bean has a very elaborated life cycle which gives opportunities to hook up some custom code or logic in various life cycle stages. There are two distinct spring containers one is bean factory and another is application context. Life cycle phases varies in the containers. More precisely, only one additional phase is added in case of application context. Let's see what these phases are:
• •
Instantiate: In this phase container finds the bean's definition and instantiates it. Populate properties: in this phase using the dependency injection all the properties are populated which are specified in the bean definition (in the XML file).
•
BeanNameAware: If BeanNameAware interface is implemented the factory calls the setBeanName() passing the Bean's Id.
•
BeanFactoryAware: if BeanFactoryAware interface is implemented setBeanFactory() method is called.
•
ApplicationContextAware: This step is valid only if the Application context container is used. In this phase if bean implements the ApplicationcontextAware then setApplicationContext() method is called.
•
Pre-initialization: If any BeanPostProcessors are associated with the bean then their postProcessBeforeInitialization() methods will be called.
•
InitializingBean / init-method: If an init-method is specified for the bean then it is called. Using init() method ,we can initialize bean through its lifecycle events.
Usage: <beans> <bean id="myBean” class=”com.clickandbuy.MyBean” init-method=”init”/> </beans>
•
Call custom init-method: If there are any BeanPostProcessors are associated then postProcessAfterInitialization() is called.
Above are the lifecycle phase when a bean becomes ready to use in the container. An existing bean can be removed from the container in two ways:
•
DisposableBean / destroy-method: If bean implements the DisposableBean interface then destroy() method is called.
Usage: <beans> <bean id="testDestBean" class="com.clickandbuy.TestBean" destroy-method="cleanup"/> </beans>
• •
Call-custom destroy: if custom-destroy method is specified then it is called.
AutoProxying: • Spring has a facility of autoproxy that enables the container to generate proxies for us.we create autoproxy creator beans. • Spring provides two classes to support this: • BeanNameAutoProxyCreator - This proxy is used to identify beans to proxy through a list of names. It checks the matches that are direct, “xxx” and “*xxx”. • DefaultAdvisorAutoProxyCreator - This proxy is the implementation of BeanPostProcessor which creates AOP proxies. These AOP proxies are based on BeanFactory’s all Candidate Advisors. It is a generic class which does not have a specific code to handle any specific aspects. • Inner Beans: • Spring IOC allows Inner Beans declaration. We can declare a bean inside a beans. But, it has few restriction. Inner Beans are like anonymous beans where it is created and used on the fly. this beans cannot be used outside the enclosing beans. So, it is wise to avoid declaring the 'ID' or 'SCOPE' attributes for them. Because, these values will be ignored by the container. Only the enclosing beans can access them. • Usage: <beans> <bean id="InventoryManager” class=”com.clickandbuy.InvManager”> <property name=”slots”> <bean class=”com.clickandbuy.HeadSlot”/>
<bean class=”com.clickandbuy.SholderSlot”/> </property> </beans>
•
There are two ways in which clients can use the functionality of the Spring Framework--the BeanFactory and the ApplicationContext
•
BeanFactory • The BeanFactory is the primary component of Core Container. • A BeanFactory is like a factory class that contains a collection of beans • As the name suggest the BeanFactory instantiate, configure and manages all beans defined. These beans typically collaborate with one another, and thus have dependencies between themselves • BeanFactory is an implementation of the Factory design pattern enables objects to be retrieved by name,and manage relationships between objects • Bean factories support two modes of object • Sinleton • Prototype • A BeanFactory is represented byt he interface org.springframework.beans.factory.BeanFactory, and it is having multiple implementations • The BeanFactory interface: • boolean containsBean(String); • Object getBean(String); • Object getBean(String,Class); • Class getType(String name); • boolean isSingleton(String); • String[] getAliases(String); • The most commonly used simple BeanFactory implementation is org.springframework.beans.factory.xml.XmlBeanFactory XmlBeanFactory • •
•
XMLBeanFactory loads beans based on definitions in an XML file. The beans are lazily loaded by the BeanFactory i.e. unless the beans are to be used it does not load them. Each bean can be a POJO or a FactoryBean. Usage:
InputStream is=new FileInputStream(“beans.xml”); BeanFactory factory = new XMLBeanFactory(is); MyBean mybean = (MyBean)factory.getBean("mybean" ); (OR) Resource res = new FileSystemResource("beans.xml"); XmlBeanFactory factory=new XmlBeanFactory(res); (OR)
ClassPathResource res = new ClassPathResource("beans.xml"); XmlBeanFactory factory = new XmlBeanFactory(res); When any of the above lines are executed all beans are present in the “configuration” file(s) are instantiated and stored in the bean factory. Once the bean factory is loaded the bean can be retrieved. BeanClassName beanObj=(BeanClassName)factory.getBean(“beanName”); •
Application Context: • The Spring context is a configuration file that provides context information to the Spring framework • Build on top of core container • It provides a way to access objects in a framework-style manner in a fashion somewhat reminiscent of JNDI-registry • Core module's BeanFactory make it container but Context module make it framework • An ApplicationContext is much the same as BeanFactory. Both load bean definitions, wire beans together, and dispense beans upon request. • But the ApplicationContext is more powerful container then BeanFactory. It inherits the BeanFactory interface so it provide all the functionality which are there in BeanFactory interface along with the following extra added features: •
Application contexts provide a means for resolving text messages from the properties files, including support for internationalization (I18N).
•
Application contexts provide a generic way to load file resources like images.
•
Application contexts can publish events to beans that are registered as listeners.
•
Supports validation, scheduling functionality
•
Provide event - propagation, resource loading functionality
•
It includes enterprise services such as JNDI, EJB
• There are various implementations of ApplicationContext is available in spring world but most commonly used implementations are given below: • ClassPathXmlApplicationContext • FileSystemXmlApplicationContext • XmlWebApplicationContext • ClassPathXmlApplicationContext - Loads a context definition from an XML file located in the classpath, treating context definition files as classpath resources. • FileSystemXmlApplicationContext - Loads a context definition from an XML file in the file system.
•
XmlWebApplicationContext - Loads context definitions from an XML file contained within a web application.
•
Example:
ClassPathXmlApplicationContext appContext = new ClassPathXmlApplicationContext( new String[] {"applicationContext.xml", "applicationContext-part2.xml"}); BeanFactory factory = (BeanFactory) appContext;
•
Expression Language: • • •
The Expression Language module provides a powerful expression language for querying and manipulating an object graph at runtime. It can be seen as an extension of the unified expression language (unified EL) as specified in the JSP 2.1 specification but offers additional features ,most notably method invocation and basic string templating functionality. Features • Literal expressions • Boolean and relational operators • Regular expressions •
Class expressions
•
Accessing properties, arrays, lists, maps
•
Method invocation
•
Relational operators
•
Assignment
•
Calling constructors
•
Bean references
•
Array construction
•
Inline lists
•
Ternary operator
•
Variables
•
User defined functions
•
Collection projection
•
Collection selection
•
Templated expressions
A typical IOC container would look like:
Bean
Bean BeanFactory
Bean
Bean
Bean Bean
BeanFactory Application Context
•
An IOC can have multiple ApplicationContexts.
•
ApplicationContext can also refer other application context.
•
Applicationcontext can contain another applicationcontext.
•
Multiple beanfactories can be inserted in an applicationcontext.
4.1.2 Data Access | Integration The Data Access/Integration layer consists of following modules: • JDBC • ORM • OXM • JMS • Transaction 4.1.2.1 OXM Module: • What is OXM: • Spring OXM stands for Spring Object XML Mappers and it is a module available in Spring to ease the mapping between java objects and XML documents.OXM is an abbreviation for Object-to-XML-Mapping
•
An O/X Mapper allows we to map Java objects to XML-Data and XML-Data to Java objects. This is also known as XML-Marshalling or XML-Serialization
•
The OXM module provides an abstraction layer for using a number of Object/XML mapping implementations. Supported technologies include JAXB, Castor, XMLBeans,
JiBX and XStream. •
JAXB is a framework or architecture,not an implementation.
•
Within the field of O/X mapping, a marshaller is responsible for serializing an object (graph) to XML. In similar fashion, an unmarshaller deserializes the XML to an object graph. This XML can take the form of a DOM document, an input or output stream, or a SAX handler.
•
Spring OXM has the following characteristics.
•
Simple setting - The marshallers can be configured as any other bean in our application context. Also, it provides 'oxm' namespace, which makes it easier to define Marshaller that uses JAXB2, XmlBeans, JiBX, etc.
•
Consistent interface - Spring's O/X mapping operates through two global interfaces which are Marshaller/Unmarshaller, These abstractions allow us to switch O/X mapping frameworks with relative ease, with little or no changes required on the classes that do the marshalling. Also, it can be used by mixing (mix and match) OX Mapping Framework.
•
Consistent exception hierarchy - Provides Root Exception called XmlMappingException for handling Exception that occurs during Mapping(Serialization).
•
Marshaller and Unmarshaller: A marshaller serializes an object to XML, and an unmarshaller deserializes XML stream
to an object.
•
• •
Marshaller: The Marshaller class is responsible for governing the process of serializing Java content trees back into XML data Spring abstracts all marshalling operations behind the org.springframework.oxm.Marshaller interface, the main methods of which is listed below.
public interface Marshaller { /** * Marshals the object graph with the given root into the provided Result. */ void marshal(Object graph, Result result) throws XmlMappingException, IOException; /** * Indicates whether this marshaller can marshal instances of the supplied type. */ boolean supports(Class clazz); } •
• •
UnMarshaller: The Unmarshaller class is responsible for deserialize a given XML Stream to an Object graph. Similar to the Marshaller , there is the org.springframework.oxm.Unmarshaller interface.
public interface Unmarshaller { /** * Unmarshals the given Source into an object graph. */ Object unmarshal(Source source) throws XmlMappingException, IOException; /** * Indicates whether this unmarshaller can unmarshal instances of the supplied type. */ boolean supports(Class clazz); } Example: A person XML document ( person.xml ): <?xml version="1.0"?> <person xmlns="http://www.example.com/person"> <firstName>first name</firstName> <lastName>last name</firstName> </pers Using DOM, outputting the first name looks something like:
DocumentBuilder documentBuilder = DocumentBuilderFactory.newDocumentBuilder( ); Document doc = documentBuilder.parse(new File("person.xml")); Element element = doc.getDocumentElement( ); NodeList firstNames = element.getElementsByTagName("firstName"); Element firstName = (Element) firstName.item(0); System.out.println(firstName.getTextContent( )); With a data binding framework, we can write much simpler code Example : Unmarshalling to a Person Object Unmarshaller unmarshaller = DataBindingFactory.newUnmarshaller( ); Person person = (Person) unmarshaller.unmarshal(new File("person.xml")); System.out.println(person.getFirstName()); Here The first line uses a factory class in our fictional framework to obtain a new instance of the Unmarshaller interface for this framework. The second line passes a File object for our document to the unmarshaller and returns an instance the Person class. Finally, we call the getFirstName( ) method on this object and output the result to the console. Example : Marshalling a Person Object Person person = new Person( ); person.setFirstName("First Name"); person.setLastName("Last Name"); Marshaller marshaller = DataBindingFactory.newMarshaller( ); marshaller.marshal(person, new FileWriter("person.xml")); The code above should raise a question: • how did the unmarshaller know to create a Person object? And • how did the marshaller know to create that specific XML structure and not, The answer to both questions could be that we need to explicitly tell the unmarshaller and marshaller about our Person class and that we want the properties to result in elements, not attributes: // for the unmarshaller unmarshaller.addMapping(Person.class, "http://www.example.com/person", "person"); // for the marshaller marshaller.addMapping(Person.class, "http://www.example.com/person", "person"); marshaller.setMarshalPropertiesAsElements(Person.class, true); There are different ways to do this: • Write a SAX parser and create Java objects as we go • Parse a DOM tree, and create ourr particular objects from them • Use a specialized API such as JAXB, Apache Commons Betwixt, etc. •
JAXB ( Java Architecture for XML Binding ):
Spring provides Jaxb2Maeshaller that uses JAXB 2.0 API. JAXB stands for Java API for XML binding and it can be used to marshall and unmarshall XML documents with simplified configuration. JAXB allows Java developers to access and process XML data without having to know XML or XML processing.
Two main JAXB components are: The binding compiler - which binds a given XML schema to a set of generated Java classes The binding runtime framework - which provides unmarshalling, marshalling, and validation functionalities The JAXB binding compiler (or xjc) : The JAXB binding compiler transforms an XML schema into a collection of Java classes that match the structure described in the XML schema. These classes are annotated with special JAXB annotations, which provide the runtime framework with the mappings it needs to process the corresponding XML documents. The binding runtime framework : an efficient and easy-to-use mechanism for unmarshalling (or reading) and marshalling (or writing) XML documents. Combined, these two components produce a technology that lets Java developers easily manipulate XML data in the form of Java objects, without having to know the nitty-gritty details of the Simple API for XML Processing (SAX) or the Document Object Model (DOM), or even the subtleties of XML Schema.
The general steps in the JAXB data binding process are:
• • • • • • •
Generate classes. An XML schema is used as input to the JAXB binding compiler to generate JAXB classes based on that schema. Compile classes. All of the generated classes, source files, and application code must be compiled. Unmarshal. XML documents written according to the constraints in the source schema are unmarshalled by the JAXB binding framework. Generate content tree. The unmarshalling process generates a content tree of data objects instantiated from the generated JAXB classes; this content tree represents the structure and content of the source XML documents. Validate (optional). The unmarshalling process optionally involves validation of the source XML documents before generating the content tree. Process the content. The client application can modify the XML data represented by the Java content tree by means of interfaces generated by the binding compiler. Marshal. The processed content tree is marshalled out to one or more XML output documents. The content may be validated before marshalling.
Generate Java classes using the JAXB compiler:
•
The JAXB compiler binds an XML schema to a set of Java classes. An XML schema is an XML document that describes, very precisely, the elements and attributes authorized in a certain type of XML document.
•
JAXB simplifies access to an XML document from a Java program by presenting the XML document to the program in a Java format. The first step in this process is to bind the schema for the XML document into a set of Java classes that represents the schema.
•
Example ( profileData.xsd )
<?xml version="1.0" encoding="utf-8" standalone="no"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="qualified" targetNamespace="http://comarch.clickandbuy.com/webservices/registration_0_9/" xmlns:cab="http://comarch.clickandbuy.com/webservices/registration_0_9/"> <xs:complexType name="CustomerProfileData"> <xs:annotation> <xs:documentation>Customer profile data</xs:documentation> </xs:annotation> <xs:sequence maxOccurs="1" minOccurs="1"> <xs:element name="emailAddress" type="cab:Email" minOccurs="1" maxOccurs="1"> </xs:element> <xs:element name="mobilePhoneNumber" type="cab:MSISDN" minOccurs="0" maxOccurs="1"> </xs:element> </xs:sequence> </xs:complexType> <xs:simpleType name="Email"> <xs:annotation> <xs:documentation>e-mail address</xs:documentation> </xs:annotation> <xs:restriction base="xs:string"> <xs:minLength value="0" /> <xs:maxLength value="50" /> <xs:pattern value="([-_.A-Za-z0-9]+)@([-_.A-Za-z0-9]+)\.[A-Za-z]{2,}" /> </xs:restriction> </xs:simpleType> <xs:simpleType name="MSISDN"> <xs:annotation> <xs:documentation>MSISDN with prefix replaced by '+' </xs:documentation> </xs:annotation> <xs:restriction base="xs:string"> <xs:pattern value="\+[1-9]([0-9]{10,14})"></xs:pattern>
</xs:restriction> </xs:simpleType> <xs:complexType name="AddressDetails"> <xs:annotation> <xs:documentation>Address details</xs:documentation> </xs:annotation> <xs:sequence maxOccurs="1" minOccurs="1"> <xs:element name="zip" type="cab:ZipCode" minOccurs="0" maxOccurs="1"> </xs:element> <xs:element name="city" type="cab:City" minOccurs="1" maxOccurs="1"> </xs:element> </xs:sequence> </xs:co complexType> <xs:simpleType name="ZipCode"> <xs:annotation> <xs:documentation>ZIP code</xs:documentation> </xs:annotation> <xs:restriction base="xs:string"> <xs:maxLength value="30"></xs:maxLength> <xs:minLength value="0"></xs:minLength> </xs:restriction> </xs:simpleType> <xs:simpleType name="City"> <xs:annotation> <xs:documentation>City</xs:documentation> </xs:annotation> <xs:restriction base="xs:string"> <xs:maxLength value="100"></xs:maxLength> <xs:minLength value="0"></xs:minLength> </xs:restriction> </xs:simpleType> </xs:schema>
The command line tool xjc runs the JAXB compiler. To run the JAXB compiler against our schema, we run the following command: $xjc profileData .xsd -p com.clickandbuy.comarch.api.schema.registration -d src/generated Some of the more useful options are described here: • -d <dir>: Place the generated files into this directory. • -p <package>: Place the generated files in this package. • -nv: Don't perform strict validation of the input schema. • -httpproxy <proxy>: Use this if you are behind a proxy. Takes the format [user[:password]@]proxyHost[:proxyPort]. • -classpath <arg>: Specify the classpath, if necessary. • -readOnly: Generates read-only source code files, if our OS supports this. The list of generated classes is shown here:
CustomerProfileData.java AddressDetails.java ObjectFactory.java JAXB Mapping of XML Schema Built-in Data Types XML Schema Type
Java Data Type
xsd:string
java.lang.String
xsd:integer
java.math.BigInteger
xsd:int
int
xsd:long
long
xsd:short
short
xsd:decimal
java.math.BigDecimal
xsd:float
float
xsd:double
double
xsd:boolean
boolean
xsd:byte
byte
xsd:QName
javax.xml.namespace.QName
xsd:dateTime
javax.xml.datatype.XMLGregorianCalendar
xsd:base64Binary
byte[]
xsd:hexBinary
byte[]
xsd:unsignedInt
long
xsd:unsignedShort
int
xsd:unsignedByte
short
xsd:time
javax.xml.datatype.XMLGregorianCalendar
xsd:date
javax.xml.datatype.XMLGregorianCalendar
xsd:g
javax.xml.datatype.XMLGregorianCalendar
xsd:anySimpleType java.lang.Object xsd:anySimpleType java.lang.String xsd:duration
javax.xml.datatype.Duration
xsd:NOTATION
javax.xml.namespace.QName
Unmarshalling an XML document
• •
Unmarshalling is the process of converting an XML document into a corresponding set of Java objects. Unmarshalling an XML document means creating a tree of content objects that represents the content and organization of the document. The content tree is not a DOM-based tree. In fact, content trees produced through JAXB can be more efficient in terms of memory use than DOM-based trees.
•
To unmarshall an XML document:
Import java.io.File; import javax.xml.bind.JAXBContext; impor javax.xml.bind.JAXBException; import javax.xml.bind.Unmarshaller; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlType; import javax.xml.bind.annotation.XmlValue; public class PersonDataUnmarshaller{ public static void main(String[] args) throws JAXBException { JAXBContext context=JAXBContext.newInstance("person"); Unmarshaller unmarshaller=context.createUnmarshaller(); Person person=(Personunmarshaller.unmarshal(new File("person.xml")); System.out.println(person.getFirstName()); } }
Here prerson.xml is an example XML document that conforms to the schema file from which the JAB-generated Java classes and interfaces are created, and Person is the root object in the XML document. An application can directly create java objects by using the ObjectFactory created by the xjc process.First, we get an instance of ObjectFactory.This factory instance is then used to create a Person object. Marshalling an XML document •
•
Marshalling is the process of generating XML from the Java objects. Marshalling means converting a javaobject tree into equivalent XML.
•
To marshall an XML document:
Import java.io.File; import javax.xml.bind.JAXBContext; impor javax.xml.bind.JAXBException; import javax.xml.bind.Unmarshaller; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlType; import javax.xml.bind.annotation.XmlValue; public class PersonDataUnmarshaller{ public static void main(String[] args) throws JAXBException { JAXBContext context=JAXBContext.newInstance("person"); Marshaller personMarshaller=context.createMarshaller(); Person person=new Person(); CustomerProfileData profileData=new CustomerProfileData(); profileData.setDateOfBirth(“9-5-1984”); person.setCustomerProfileData(profileData); Person person=(personMarshaller .marshal(new File("person.xml")); System.out.println(person.getFirstName()); } }
Here prerson.xml is an example XML document that conforms to the schema file from which the JAB-generated Java classes and interfaces are created, and Person is the root object in the XML document. An application can directly create java objects by using the ObjectFactory created by the xjc process.First, we get an instance of ObjectFactory.This factory instance is then used to create a Person object. (OR) Setting for using Jaxb2Marshaller is as follows: <bean id="comarch_0_9_jaxb2Marshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller"> <property name="schemas"> <list> <value>classpath:api/profileData.xsd</value> </list> </property> <property name="contextPath" value="com.clickandbuy.comarch.api.schema.registration /> </bean>
Advantages of JAXB: • No need to create and use a parser and no need to write a content handler with callback methods. • Developers can access and process XML data without having to know XML or XML processing. • Using STAX(Streaming API for XML), comes inclusive in JAXB API, one can also define the part(s) of xml to be unmarshalled and hence further reducing the memory load. • New XML documents can also be created using Marshalling. 4.1.2.2 ORM ( Object Relational Mapping ) Module: • What is ORM: • The Spring Framework supports integration with Hibernate, Java Persistence API (JPA), Java Data Objects (JDO) and iBATIS SQL Maps for resource management, data access object (DAO) implementations, and transaction strategies. • For example, for Hibernate there is first-class support with several convenient IoC features that address many typical Hibernate integration issues. You can configure all of the supported features for O/R (object relational) mapping tools through Dependency Injection. They can participate in Spring's resource and transaction management, and they comply with Spring's generic transaction and DAO exception hierarchies • Benefits of using the Spring Framework to create our ORM DAOs include: • Easier testing. Spring's IoC approach makes it easy to swap the implementations and configuration locations of Hibernate SessionFactory instances, JDBC DataSource instances, transaction managers, and mapped object implementations (if needed). This in turn makes it much easier to test each piece of persistence-related code in isolation.
•
Common data access exceptions. Spring can wrap exceptions from our ORM tool, converting them from proprietary (potentially checked) exceptions to a common runtime DataAccessException hierarchy. This feature allows you to handle most persistence exceptions, which are non-recoverable, only in the appropriate layers, without annoying boilerplate catches, throws, and exception declarations. You can still trap and handle exceptions as necessary. Remember that JDBC exceptions (including DB-specific dialects) are also converted to the same hierarchy, meaning that you can perform some operations with JDBC within a consistent programming model.
•
General resource management. Spring application contexts can handle the location and configuration of Hibernate SessionFactory instances, JPA EntityManagerFactory instances, JDBC DataSource instances, iBATIS SQL Maps configuration objects, and other related resources. This makes these values easy to manage and change. Spring offers efficient, easy, and safe handling of persistence resources. For example, related code that uses Hibernate generally needs to use the same Hibernate Session to ensure efficiency and proper transaction handling. Spring makes it easy to create and bind a Session to the current thread transparently, by exposing a current Session through the Hibernate SessionFactory. Thus Spring solves many chronic problems of typical Hibernate usage, for any local or JTA transaction environment.
•
Integrated transaction management. You can wrap our ORM code with a declarative, aspect-oriented programming (AOP) style method interceptor either through the @Transactional annotation or by explicitly configuring the transaction AOP advice in an XML configuration file. In both cases, transaction semantics and exception handling (rollback, and so on) are handled for you. As discussed below, in
Resource and transaction management, you can also swap various transaction managers, without affecting our ORM-related code. For example, you can swap between local transactions and JTA, with the same full services (such as declarative transactions) available in both scenarios. Additionally, JDBC-related code can fully integrate transactionally with the code you use to do ORM. This is useful for data access that is not suitable for ORM, such as batch processing and BLOB streaming, which still need to share common transactions with ORM operations. 4.1.2.2 JMS ( Java Message Service ) Module: • Introduction: • Spring provides a JMS abstraction framework that simplifies the use of the JMS API and shields the user from differences between the JMS 1.0.2 and 1.1 APIs. • The package org.springframework.jms.core provides the core functionality for using JMS. It contains JMS template classes that simplifies the use of the JMS by handling the creation and release of resources, much like the JdbcTemplate does for JDBC. • The JMS template follows the same design. The classes offer various convenience methods for the sending of messages, consuming a message synchronously, and exposing the JMS session and message producer to the user. • The package org.springframework.jms.support provides JMSException translation functionality. The translation converts the checked JMSException hierarchy to a mirrored hierarchy of unchecked exceptions. If there are any provider specific subclasses of the checked javax.jms.JMSException, this exception is wrapped in the unchecked UncategorizedJmsException.
•
•
The package org.springframework.jms.support.converter provides a MessageConverter abstraction to convert between Java objects and JMS messages.
•
The package org.springframework.jms.support.destination provides various strategies for managing JMS destinations, such as providing a service locator for destinations stored in JNDI.
•
Finally, the package org.springframework.jms.connection provides an implementation of the ConnectionFactory suitable for use in standalone applications. It also contains an implementation of Spring's PlatformTransactionManager for JMS (the cunningly named JmsTransactionManager). This allows for seamless integration of JMS as a transactional resource into Spring's transaction management mechanisms.
JMS API Architecture A JMS application is composed of the following parts.
• A JMS provider is a messaging system that implements the JMS interfaces and provides administrative and control features. An implementation of the J2EE platform at release 1.3 includes a JMS provider. TM • JMS clients are the programs or components, written in the Java programming language, that produce and consume messages. • Messages are the objects that communicate information between JMS clients. • Administered objects are preconfigured JMS objects created by an administrator for the use of clients. The two kinds of administered objects are destinations and connection factories • Native clients are programs that use a messaging product's native client API instead of the JMS API. An application first created before the JMS API became available and
subsequently modified is likely to include both JMS and native clients. The below figure illustrates the way these parts interact.
Administrative tools allow you to bind destinations and connection factories into a Java TM Naming and Directory Interface (JNDI) API namespace. A JMS client can then look up the administered objects in the namespace and then establish a logical connection to the same objects through the JMS provider. •
Messaging Domains
•
Before the JMS API existed, most messaging products supported either the point-topoint or the publish/subscribe approach to messaging. The JMS Specification provides a separate domain for each approach and defines compliance for each domain. A standalone JMS provider may implement one or both domains. A J2EE provider must implement both domains.
•
In fact, most current implementations of the JMS API provide support for both the pointto-point and the publish/subscribe domains, and some JMS clients combine the use of both domains in a single application. In this way, the JMS API has extended the power and flexibility of messaging products.
•
Point-to-point Messaging Domain
•
A point-to-point (PTP) product or application is built around the concept of message queues, senders, and receivers. Each message is addressed to a specific queue, and receiving clients extract messages from the queue(s) established to hold their messages. Queues retain all messages sent to them until the messages are consumed or until the messages expire. PTP messaging has the following characteristics and is illustrated in below figure.
• •
Each message has only one consumer.
• A sender and a receiver of a message have no timing dependencies. The receiver can fetch the message whether or not it was running when the client sent the message. • The receiver acknowledges the successful processing of a message. Use PTP messaging when every message you send must be processed successfully by one consumer. •
Publish/Subscribe Messaging domain
•
In a publish/subscribe (pub/sub) product or application, clients address messages to a topic. Publishers and subscribers are generally anonymous and may dynamically publish or subscribe to the content hierarchy. The system takes care of distributing the messages arriving from a topic's multiple publishers to its multiple subscribers. Topics retain messages only as long as it takes to distribute them to current subscribers. Pub/sub messaging has the following characteristics.
• • • •
• Each message may have multiple consumers.
• Publishers and subscribers have a timing dependency. A client that subscribes to a topic can consume only messages published after the client has created a subscription, and the subscriber must continue to be active in order for it to consume messages. • The JMS API relaxes this timing dependency to some extent by allowing clients to create durable subscriptions. • Durable subscriptions can receive messages sent while the subscribers are not active. Durable subscriptions provide the flexibility and reliability of queues but still allow clients to send messages to many recipients. • Use pub/sub messaging when each message can be processed by zero, one, or many consumers. The below figure illustrates pub/sub messaging.
•
Message Consumption
Messaging products are inherently asynchronous in that no fundamental timing dependency exists between the production and the consumption of a message. However, the JMS Specification uses this term in a more precise sense. Messages can be consumed in either of two ways:
• Synchronously. A subscriber or a receiver explicitly fetches the message from the
destination by calling the receive method. The receive method can block until a message arrives or can time out if a message does not arrive within a specified time limit. • Asynchronously. A client can register a message listener with a consumer. A message listener is similar to an event listener. Whenever a message arrives at the destination, the JMS provider delivers the message by calling the listener's onMessage method, which acts on the contents of the message. •
The JMS API Programming Model The basic building blocks of a JMS application consist of • Administered objects • Sessions • Message producers • Message consumers • Messages
•
Administered objects •
•
•
Two parts of a JMS application--destinations and connection factories--are best maintained administratively rather than programmatically. The technology underlying these objects is likely to be very different from one implementation of the JMS API to another. Therefore, the management of these objects belongs with other administrative tasks that vary from provider to provider. JMS clients access these objects through interfaces that are portable, so a client application can run with little or no change on more than one implementation of the TM JMS API. Ordinarily, an administrator configures administered objects in a Java TM Naming and Directory Interface (JNDI) API namespace, and JMS clients then look TM them up, using the JNDI API. J2EE applications always use the JNDI API. With the J2EE Software Development Kit (SDK) version 1.3.1, you use a tool called j2eeadmin to perform administrative tasks. For help on the tool, type j2eeadmin with no arguments.
•
Connection Factories
•
A connection factory is the object a client uses to create a connection with a provider. A connection factory encapsulates a set of connection configuration parameters that has been defined by an administrator. A pair of connection factories come preconfigured with the J2EE SDK and are accessible as soon as you start the service. Each connection factory is an instance of either the QueueConnectionFactory or the TopicConnectionFactory interface. With the J2EE SDK, for example, you can use the default connection factory objects, named QueueConnectionFactory and TopicConnectionFactory, to create connections. You can also create new connection factories by using the following commands:
•
j2eeadmin -addJmsFactory jndi_name queue j2eeadmin -addJmsFactory jndi_name topic
•
At the beginning of a JMS client program, you usually perform a JNDI API lookup of the connection factory. For example, the following code fragment obtains an InitialContext object and uses it to look up the QueueConnectionFactory and the TopicConnectionFactory by name:
Context ctx = new InitialContext(); QueueConnectionFactory queueConnectionFactory = (QueueConnectionFactory) ctx.lookup("QueueConnectionFactory"); TopicConnectionFactory topicConnectionFactory = (TopicConnectionFactory) ctx.lookup("TopicConnectionFactory");
•
Calling the InitialContext method with no parameters results in a search of the current classpath for a vendor-specific file named jndi.properties. This file indicates which JNDI API implementation to use and which namespace to use.
• •
Destinations A destination is the object a client uses to specify the target of messages it produces and the source of messages it consumes. In the PTP messaging domain, destinations are called queues, and you use the following J2EE SDK command to create them: j2eeadmin -addJmsDestination queue_name queue
•
In the pub/sub messaging domain, destinations are called topics, and you use the following J2EE SDK command to create them: j2eeadmin -addJmsDestination topic_name topic
•
•
A JMS application may use multiple queues and/or topics. In addition to looking up a connection factory, you usually look up a destination. For example, the following line of code performs a JNDI API lookup of the previously created topic MyTopic and assigns it to a Topic object:
Topic myTopic = (Topic) ctx.lookup("MyTopic");
•
•
• •
The following line of code looks up a queue named MyQueue and assigns it to a Queue object: Queue myQueue = (Queue) ctx.lookup("MyQueue"); Connections A connection encapsulates a virtual connection with a JMS provider. A connection could represent an open TCP/IP socket between a client and a provider service daemon. You use a connection to create one or more sessions. Like connection factories, connections come in two forms, implementing either the QueueConnection or the TopicConnection interface. For example, once you have a QueueConnectionFactory or a TopicConnectionFactory object, you can use it to create a connection:
QueueConnection queueConnection = queueConnectionFactory.createQueueConnection(); TopicConnection topicConnection = topicConnectionFactory.createTopicConnection(); •
When an application completes, you need to close any connections that you have created. Failure to close a connection can cause resources not to be released by the JMS provider. Closing a connection also closes its sessions and their message producers and message consumers. queueConnection.close(); topicConnection.close();
•
•
Before our application can consume messages, you must call the connection's start method.If you want to stop message delivery temporarily without closing the connection, you call the stop method.
Sessions • A session is a single-threaded context for producing and consuming messages • We use sessions to create message producers,message consumers,and messages. • Sessions serialize the execution of message listeners • Sessions, like connections, come in two forms, implementing either the QueueSession or the TopicSession interface • Example:
TopicSession topicSession=topicConnection.createTopicSession(false,Session.AUTO_ACKNOWLEDGE); •
Message producers • A message producer A message producer is an object created by a session and is used for sending messages to a destination. The PTP form of a message producer implements the QueueSender interface. The pub/sub form implements the TopicPublisher interface. • Example: QueueSender queueSender = queueSession.createSender(myQueue); TopicPublisher topicPublisher = topicSession.createPublisher(myTopic);
•
Message consumers • A message consumer is an object created by a session and is used for receiving messages sent to a destination. A message consumer allows a JMS client to register interest in a destination with a JMS provider. The JMS provider manages the delivery of messages from a destination to the registered consumers of the destination. • The PTP form of message consumer implements the QueueReceiver interface. The pub/sub form implements the TopicSubscriber interface. • For example, you use a QueueSession to create a receiver for the queue myQueue, and you use a TopicSession to create a subscriber for the topic myTopic:
QueueReceiver queueReceiver = queueSession.createReceiver(myQueue); TopicSubscriber topicSubscriber = topicSession.createSubscriber(myTopic);
•
•
You use the TopicSession.createDurableSubscriber method to create a durable topic subscriber.Once you have created a message consumer, it becomes active, and you can use it to receive messages. You can use the close method for a QueueReceiver or a TopicSubscriber to make the message consumer inactive. Message delivery does not begin until you start the connection you created by calling the start method With either a QueueReceiver or a TopicSubscriber, you use the receive method to consume a message synchronously. You can use this method at any time after you call the start method:
queueConnection.start(); Message m = queueReceiver.receive(); topicConnection.start(); Message m = topicSubscriber.receive(1000); // time out after a second •
Message Listeners • A message listener is an object that acts as an asynchronous event handler for messages. This object implements the MessageListener interface, which contains one method, onMessage. In the onMessage method, you define the actions to be taken when a message arrives. You register the message listener with a specific QueueReceiver or TopicSubscriber by using the setMessageListener method. For example, if you define a class named TopicListener that implements the MessageListener interface, we can register the message listener as follows:
TopicListener topicListener = new TopicListener(); topicSubscriber.setMessageListener(topicListener);
• •
•
After we register the message listener, you call the start method on the QueueConnection or the TopicConnection to begin message delivery. (If you call start before you register the message listener, you are likely to miss messages.) Once message delivery begins, the message consumer automatically calls the message listener's onMessage method whenever a message is delivered. The onMessage method takes one argument of type Message, which the method can cast to any of the other message types A message listener is not specific to a particular destination type. The same listener can obtain messages from either a queue or a topic, depending on whether the listener is set by a QueueReceiver or a TopicSubscriber object. A message
• •
•
•
listener does, however, usually expect a specific message type and format. Moreover, if it needs to reply to messages, a message listener must either assume a particular destination type or obtain the destination type of the message and create a producer for that destination type. Your onMessage method should handle all exceptions. It must not throw checked exceptions, and throwing a RuntimeException, though possible, is considered a programming error. The session used to create the message consumer serializes the execution of all message listeners registered with the session. At any time, only one of the session's message listeners is running.
Message Selectors • If your messaging application needs to filter the messages it receives, you can use a JMS API message selector, which allows a message consumer to specify the messages it is interested in. Message selectors assign the work of filtering messages to the JMS provider rather than to the application. For an example of the use of a message selector • A message selector is a String that contains an expression. The syntax of the expression is based on a subset of the SQL92 conditional expression syntax. The createReceiver, createSubscriber, and createDurableSubscriber methods each have a form that allows you to specify a message selector as an argument when you create a message consumer. Messages • The ultimate purpose of a JMS application is to produce and to consume messages that can then be used by other software applications. JMS messages have a basic format that is simple but highly flexible, allowing you to create messages that match formats used by non-JMS applications on heterogeneous platforms. •
•
A JMS message has three parts: •
A Header
•
Properties (optional)
•
A body
Messages Headers • A JMS message header contains a number of predefined fields that contain values that both clients and providers use to identify and to route messages. Below Table lists the JMS message header fields and indicates how their values are set.) For example, every message has a unique identifier, represented in the header field JMSMessageID. The value of another header field, JMSDestination, represents the queue or the topic to which the message is sent. Other fields include a timestamp and a priority level. • Each header field has associated setter and getter methods, which are documented in the description of the Message interface. Some header fields are intended to be set by a client, but many are set automatically by the send or the publish method, which overrides any client-set values.
Header Field
Set By
JMSDestination
send or publish method
JMSDeliveryMode
send or publish method
JMSExpiration
send or publish method
JMSPriority
send or publish method
JMSMessageId
send or publish method
JMSTimestamp
send or publish method
JMSCorrelationID
Client
JMSReplyTo
Client
JMSType
Client
JMSRedelivered
JMS provider
•
•
Messages properties • we can create and set properties for messages if you need values in addition to those provided by the header fields. • we can use properties to provide compatibility with other messaging systems, or you can use them to create message selectors • The JMS API provides some predefined property names that a provider may support. The use of either predefined properties or user-defined properties is optional. Message Bodies • The JMS API defines five message body formats, also called message types, which allow you to send and to receive data in many different forms and provide compatibility with existing messaging formats. Below Table describes these message types.
Message Type
Body Contains
TextMessage
A java.lang.String object (for example, the contents of an Extensible Markup Language file).
MapMessage
A set of name/value pairs, with names as String objects and values as primitive types in the Java programming language. The entries can be accessed sequentially by enumerator or randomly by name. The order of the entries is undefined.
BytessMessage
A stream of uninterpreted bytes. This message type is for literally encoding a body to match an existing message format.
StreamMessage
A stream of primitive values in the Java programming language, filled and read sequentially.
ObjectMessage
A Serializable object in the Java programming language.
Message
Nothing. Composed of header fields and properties only. This message type is useful when a message body is not required.
4.1.2.2 Transaction Module: •
Introduction: • The Transaction module supports programmatic and declarative transaction management for classes that implement special interfaces and for POJOs (plain old Java objects). • The Spring Framework provides a consistent abstraction for transaction management that delivers the following benefits: • Consistent programming model across different transaction APIs such as Java Transaction API (JTA), JDBC, Hibernate, Java Persistence API (JPA), and Java Data Objects (JDO). • Support for declarative transaction management. • Simpler API for programmatic transaction management than complex transaction APIs such as JTA. • Excellent integration with Spring's data access abstractions.
•
Benefits of Transaction Management: • Very easy to use, does not require any underlying transaction API knowledge • Your transaction management code will be independent of the transaction technology • Both annotation- and XML-based configuration
•
It does not require to run on a server - no server needed
•
Overview: • Transactions ensure that the data in your application (in the data source) stays consistent • Now, in Java you can handle transactions with plain SQL, with plain JDBC (a bit higher level), using Hibernate (or any other ORM library), or on an even higher level - with EJB or, finally, Spring! • Spring offers two ways of handling transactions: • Programmatic - means we have transaction management code surrounding our business code. That gives you extreme flexibility, but is difficult to maintain and, well, boilerplate • Declarative - means we separate transaction management from the business code. we only use annotations or XML based configuration.
•
Programmatic Transaction Management: Spring provides two means of programmatic transaction management: • Using the TransactionTemplate • Using a PlatformTransactionManager implementation directly We generally recommend the first approach.The second approach is similar to using the JTA UserTransaction API (although exception handling is less cumbersome).
• •
Using the TransactionTemplate The TransactionTemplate adopts the same approach as other Spring templates such as JdbcTemplate and HibernateTemplate. It uses a callback approach, to free application code from the working of acquiring and releasing resources. (No more
•
try/catch/finally.) Like other templates, a TransactionTemplate is threadsafe. Application code that must execute in a transaction context looks like this. Note that the TransactionCallback can be used to return a value:
Object result = tt.execute(new TransactionCallback() { public Object doInTransaction(TransactionStatus status) { updateOperation1(); return resultOfUpdateOperation2(); } });
• •
Using the PlatformTransactionManager You can also use the org.springframework.transaction.PlatformTransactionManager directly to manage your transaction. Simply pass the implementation of the PlatformTransactionManager you're using to your bean via a bean reference. Then, using the TransactionDefinition and TransactionStatus objects you can initiate transactions, rollback and commit.
DefaultTransactionDefinition def = new DefaultTransactionDefinition(); def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED); TransactionStatus status = txManager.getTransaction(def); try { // execute your business logic here } catch (MyException ex) { txManager.rollback(status); throw ex; } txManager.commit(status);
• •
•
Declarative Transaction Management: Spring also offers declarative transaction management. This is enabled by Spring AOP, although, as the transactional aspects code comes with Spring and may be used in a boilerplate fashion, AOP concepts do not generally have to be understood to make effective use of this code It may be helpful to begin by considering EJB CMT and explaining the similarities and differences with Spring declarative transaction management. The basic approach is similar: It's possible to specify transaction behavior (or lack of it) down to individual methods. It's possible to make a setRollbackOnly() call within a transaction context if necessary. The differences are: • Unlike EJB CMT, which is tied to JTA, Spring declarative transaction management works in any environment. It can work with JDBC, JDO, Hibernate or other transactions under the covers, with configuration changes only. • Spring enables declarative transaction management to be applied to any POJO, not just special classes such as EJBs. • Spring offers declarative rollback rules: a feature with no EJB equivalent, which we'll discuss below. Rollback can be controlled declaratively, not merely programmatically. • Spring gives you an opportunity to customize transactional behavior, using AOP. For
•
example, if you want to insert custom behavior in the case of transaction rollback, you can. You can also add arbitrary advice, along with the transactional advice. With EJB CMT, you have no way to influence the container's transaction management other than setRollbackOnly(). • Spring does not support propagation of transaction contexts across remote calls, as do high-end application servers. If you need this feature, we recommend that you use EJB. However, don't use this feature lightly. Normally we don't want transactions to span remote calls. When using TransactionProxyFactoryBean, you need to first of all specify the target object to wrap in the transactional proxy, via the target attribute.. The target object is normally a POJO bean definition. You must also specify a reference to the relevant PlatformTransactionManager. Finally, you must specify the transaction attributes. Transaction attributes contain the definition of what transaction semantics we wish to use (as discussed above), as well as where they apply. Now let's consider the following sample:
<bean id="petStoreTarget"> ... </bean> <bean id="petStore" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"> <property name="transactionManager" ref="txManager"/> <property name="target" ref="petStoreTarget"/> <property name="transactionAttributes"> <props> <prop key="insert*">PROPAGATION_REQUIRED,-MyCheckedException</prop> <prop key="update*">PROPAGATION_REQUIRED</prop> <prop key="*">PROPAGATION_REQUIRED,readOnly</prop> </props> </property> </bean>
•
The transactional proxy will implement the interfaces of the target: in this case, the bean with id petStoreTarget. (Note that using CGLIB it's possible to transactionally proxy non-interface methods of the target class as well. Set the "proxyTargetClass" property to true to force this to always happen, although it will happen automatically if the target doesn't implement any interfaces. In general, of course, we want to program to interfaces rather than classes.) It's possible (and usually a good idea) to restrict the transactional proxy to proxying only specific target interfaces, using the proxyInterfaces property. It's also possible to customize the behavior of a TransactionProxyFactoryBean via several properties inherited from org.springframework.aop.framework.ProxyConfig, and shared with all AOP proxy factories.
4.1.3 Web • The Web layer consists of following modules: • Web • Web-Servlet • Web-Struts • Web-Portlet
•
•
•
•
Spring's Web module provides basic web-oriented integration features such as multipart file-upload functionality and the initialization of the IoC container using servlet listeners and a web-oriented application context. It also contains the webrelated parts of Spring's remoting support. The Web-Servlet module contains Spring's model-view-controller (MVC) implementation for web applications. Spring's MVC framework provides a clean separation between domain model code and web forms, and integrates with all the other features of the Spring Framework. The Web-Struts module contains the support classes for integrating a classic Struts web tier within a Spring application. Note that this support is now deprecated as of Spring 3.0. Consider migrating your application to Struts 2.0 and its Spring integration or to a Spring MVC solution. The Web-Portlet module provides the MVC implementation to be used in a portlet environment and mirrors the functionality of Web-Servlet module.
4.1.4 AOP and Instrumentation
•
• •
Spring's AOP module provides an AOP Alliance-compliant aspect-oriented programming implementation allowing you to define, for example, method-interceptors and pointcuts to cleanly decouple code that implements functionality that should be separated. Using source-level metadata functionality, you can also incorporate behavioral information into your code, in a manner similar to that of .NET attributes. The separate Aspects module provides integration with AspectJ. The Instrumentation module provides class instrumentation support and classloader implementations to be used in certain application servers.
4.1.5 Test
•
The Test module supports the testing of Spring components with JUnit or TestNG. It provides consistent loading of Spring ApplicationContexts and caching of those contexts. It also provides mock objects that you can use to test your code in isolation.