Professional Documents
Culture Documents
Ver 0.1
• Analysts
Prerequisites
Course goals
• Course non-goals:
• Design patterns, Integration with technologies other than those
mentioned in course-goals.
Agenda
• Day 1
• Introduction to Spring Framework
• Day – 2
• DAO support
Agenda
• Day -3
• Integrating Struts with Spring
Introduction
In 1996, the Java programming language was still a young, exciting, up-and-coming platform.
Many developers flocked to the language because they had seen how to create rich and
dynamic web applications using applets. But they soon learned that there is more to this
strange new language than juggling animated cartoon characters. Unlike any language before
it, Java made it possible to write complex applications made up of discrete parts. They came
for the applets, but stayed for the components.
It was in December of that year that Sun Microsystems published the Java-Beans 1.00-A
specification. JavaBeans defined a software component model for Java. This specification
defined a set of coding policies that enabled simple Java objects to be reusable and easily
composed into more complex applications. Although JavaBeans were intended as a general-
purpose means of defining reusable application components, they have been primarily used
as a model for building user interface widgets. They seemed too simple to be capable of any
“real” work. Enterprise developers wanted more.
Sophisticated applications often require services such as transaction support, security and
distributed computing- services not directly provided by the JavaBeans specification.
Therefore in March 1998, Sun published the 1.0 version of the Enterprise JavaBeans (EJB)
specification. This specification extended the notion of Java components to the server side,
providing the much-needed enterprise services, but failed to continue the simplicity of the
original JavaBeans specification. In fact, except in name, EJB bears very little resemblance
to the original Javabeans specification.
Despite the fact that many successful applications have been built based on EJB, EJB never
really achieved its intended purpose: to simplify enterprise application development. Every
version of EJB specification contains the following statement: “Enterprise JavaBeans will
make it easy to write applications.” It is true that EJB’s declarative programming model
simplifies many infrastructural aspects of development, such as transactions and security.
But EJB’s are complicated in a different way by mandating deployment descriptors and
plumbing code (home and remote/local interfaces). Over time many developers became
disenchanted with EJB. As a result, its popularity has started to wane in recent years,
leaving many developers looking for an easier way.
Now Java development is coming full circle. New programming techniques, including aspect-
oriented programming (AOP) and inversion of control (IoC), are giving JavaBeans much of the
power of EJB. These techniques furnish JavaBeans with a declarative programming model
reminiscent of EJB, but without all of EJB’s complexity. No longer must you resort to writing
an unwieldy EJB component when a simple JavaBean will suffice.
And that’s where Spring steps into the picture.
J2EE applications tend to contain excessive amounts of “plumbing” code. Often it is seen that
there exists a high proportion of code that doesn’t do anything. Writing and maintaining such
plumbing code proves a major drain on resources that should be focused on the application’s business
domain.
Many J2EE applications use a distributed object model where this is inappropriate. This is one of
the major causes of excessive code and code duplication. Of course, if your business requirements
dictate a distributed architecture, you need to implement a distributed architecture and accept the
tradeoff that incurs.
The EJB component model is unduly complex. EJB was conceived as a way of reducing complexity
when implementing business logic in J2EE applications; it has not succeeded in this aim in practice.
EJB is overused. EJB was essentially designed for internally distributed, transactional applications.
While nearly all non-trivial applications are transactional, distribution should not be built into the
basic component model.
Many “J2EE design patterns” are not, in fact, design patterns, but workarounds for technology
limitations. Overuse of distribution, and use of complex APIs such as EJB, have generated many
questionable design patterns; it’s important to examine these critically and look for simpler, more
productive, approaches.
J2EE applications are hard to unit test. The J2EE APIs, and especially, the EJB component model,
do not allow ease of unit testing. It is difficult to test applications based on EJB and many other J2EE
APIs outside an application server. Yet unit testing outside an application server is essential to
achieve high test coverage. It is also vital to ensuring that tests can be run quickly during the
development or maintenance process, minimizing unproductive time waiting for redeployment.
What is Spring?
Spring is an open source framework created by Rod Johnson, Juergen Hoeller et all, to
address the complexity of enterprise application development. Spring makes it easy to use
POJO’s to achieve things that were previously only possible with EJB’s. However, Spring’s
usefulness isn’t restricted to server-side development. Any java application can benefit from
Spring in terms of simplicity, testability and loose coupling.
Inversion of control: Spring promotes loose coupling through a technique known as inversion
of control (IoC) or also known popularly as Dependency Injection (DI). When IoC is applied,
objects are passively given their dependencies instead of creating or looking for dependent
objects for themselves. You can think of IoC as JNDI in reverse – instead of an object looking
up dependencies from a container, the container gives the dependencies to the object at
instantiation without waiting to be asked.
Aspect-oriented : Spring comes with rich support for aspect-oriented programming that
enables cohesive development by separating application business logic from system services
(such as auditing and transaction management). Application objects do what they are
supposed to do – perform business logic – and nothing more. They are not responsible for
other system concerns such as logging or transactional support.
Container: Spring is a container in the sense that it contains and manages the life cycle and
configuration of application objects. You can configure how each of your beans should be
created – either create one single instance of your bean or produce a new instance every
time one is needed based on a configurable prototype – and how they should be associated
with each other. Spring should however not be confused with traditionally heavyweight EJB
containers, which are often large and cumbersome to work with.
Framework: Spring makes it possible to configure and compose complex applications from
simpler components. In Spring, application objects are composed declaratively, typically in
an XML file. Spring also provides much infrastructure functionality (transaction management,
persistence framework integration etc) leaving the development of application logic to user.
All these attributes of Spring enable you to write code that is cleaner, more manageable and
easier to test.
Why Spring?
In keeping with this philosophy, Spring was designed with the following beliefs:
• Good design is more important than the underlying technology.
• JavaBeans loosely coupled through interfaces is a good model.
• Code should be easy to test.
So how does Spring help you apply this philosophy to your applications?
• As a developer, you should always be seeking the best design for your application,
regardless of the implementation you choose. Sometimes the complexity of EJB is
warranted because of the requirements of the application. Often, this is not the case.
Many applications require few, if any, of the services provided by EJB yet are still
implemented suing this technology, for technology’s sake. If an application does not
require distribution or declarative transaction support, it is unlikely that EJB is the best
technology candidate. Yet many Java developers feel compelled to use EJB for every
Java enterprise application.
• The idea behind Spring is that you can keep your code as simple as it needs to be. If
what you want is some POJO’s to perform some services supported by transparent
transactions, you have got it. And you do not need an EJB container, you do not have to
implement special interfaces. You just have to write your code.
If you are relying on EJB’s to provide your application services, your components do not just
depend on the EJB business interface. They are also responsible for retrieving these EJB
objects from a directory, which entails a JNDI lookup and communicating with the bean’s
EJBHome interface. This is not creating a decoupled application. This is tightly coupling your
application to a specific implementation namely EJB.
With Spring, your beans depend on collaborators through interfaces. Since there are no
implementation-specific dependencies, Spring applications are very decoupled, testable and
easier to maintain. And because the Spring container is responsible for resolving the
dependencies, the active service lookup that is involved in EJB is now out of the picture and
the cost of programming to interfaces is minimized. All you need to do is create classes that
communicate with each other through interfaces and Spring takes care of the rest.
Testing J2EE applications can be difficult. If you are testing EJB’s within a container, you
have to start up a container to execute even the moist trivial of test cases. Since starting
and stopping a container is expensive, developers may be tempted to skip testing all their
components. Avoiding tests because of the rigid ness of a framework is not a good excuse.
Because Spring applications are developed with EJB’s testing is cheap. There is no J2EE
container to be started since you will be testing a POJO. And since Spring makes coding to
interfaces easy, your objects will be loosely coupled, making testing even easier.
Overview
Spring could potentially be a one-stop-shop for all your enterprise applications. However,
Spring is modular, allowing you to use parts of it, without having to bring in the rest. You can
use the bean container, with Struts on top, but you could also choose to just use the
Hibernate integration or the JDBC abstraction layer. Spring is non-intrusive, meaning
dependencies on the framework are generally none or absolutely minimal, depending on the
area of use..
The Spring framework is a layered architecture consisting of seven well-defined modules.
The Spring modules are built on top of the core container, which defines how beans are
created, configured, and managed, as shown in above figure.
Each of the modules (or components) that comprise the Spring framework can stand on its
own or be implemented jointly with one or more of the others. The functionality of each
component is as follows:
1. The Core package : is the most fundamental part of the framework and provides the
Dependency Injection features allowing you to manage bean container functionality. The
basic concept here is the BeanFactory, which provides a factory pattern removing the need
for programmatic singletons and allowing you to decouple the configuration and
specification of dependencies from your actual program logic.
2. On top of the Core package sits the Context package, providing a way to access beans in
a framework-style manner, somewhat resembling a JNDI-registry. The context package
inherits its features from the beans package and adds support for text messaging using e.g.
resource bundles, event-propagation, resource-loading and transparent creation of contexts
by, for example, a servlet container.
3. The DAO package : provides a JDBC-abstraction layer that removes the need to do tedious
JDBC coding and parsing of database-vendor specific error codes. Also, the JDBC package
provides a way to do programmatic as well as declarative transaction management, not only
for classes implementing special interfaces, but for all your POJOs (plain old java objects).
4. The ORM package : provides integration layers for popular object-relational mapping
APIs, including JDO, Hibernate and iBatis. Using the ORM package you can use all those O/R-
mappers in combination with all the other features Spring offers, like simple declarative
transaction management mentioned before.
Basic Architecture
Usage scenarios
With the building blocks described above you can use Spring in all sorts of scenarios, from applets
up to fully-fledged enterprise applications using Spring's transaction management functionality
and Web framework.
Sometimes the current circumstances do not allow you to completely switch to a different
framework. Spring does not force you to use everything within it; it's not an all-or-nothing
solution. Existing frontends using WebWork, Struts, Tapestry, or other UI frameworks can be
integrated perfectly well with a Spring-based middle-tier, allowing you to use the transaction
features that Spring offers. The only thing you need to do is wire up your business logic using an
ApplicationContext and integrate your Web UI layer using a WebApplicationContext.
Additional services such as sending email and validation, independent of the web layer enable you
to choose where to execute validation rules. Spring's ORM support is integrated with Hibernate,
JDO and iBatis.
Using for example HibernateDaoSupport, you can re-use your existing Hibernate mappings. Form
controllers seamlessly integrate the web-layer with the domain model, removing the need for
ActionForms or other classes that transform HTTP parameters to values for your domain model.
With EJB
Spring also provides an access layer and abstraction layer for Enterprise JavaBeans, enabling you
to reuse your existing POJOs and wrap them in Stateless Session Beans, for use in scalable failsafe
web applications, that might need declarative security.
Spring Jumpstart
• CurrencyConverter.java
• CurrencyConverterImpl.java
• CurrencyConverter.xml
• CurrencyConverterClient.java
Spring-enabled applications are like any Java application. They are made up of several
classes, each performing a specific purpose within the application. Difference lies in how
these classes are configured and introduced to each other. Typically a Spring application has
an XML file that describes how to configure the classes, known as Spring configuration file.
The first class that the example shows is a service class whose purpose is to print the value
of dollars converted to rupees.
The listing below shows CurrencyConverter.java, an interface that defines the contract for
the service class.
The CurrencyConverterImpl class has a single property exchangeRate. This property is simply
a double variable that will hold the exchange rate passed by its setter method. We can also
pass value through the constructor.
What is not apparent just yet is who will make a call to either the constructor or the
setExchangeRate() method to set the exchangeRate property. The Spring configurration file
(CurrencyConverter.xml) in the listing tells how to configure the CurrencyConverter service.
Finally lets see the class that loads the Spring container and uses it to retrieve the currencyConverter
service. Example 1.3 in appendix B shows this class:
package training.Spring;
import org.Springframework.beans.factory.*;
import org.Springframework.beans.factory.xml.*;
import org.Springframework.core.io.*;
The BeanFactory class used here is the Spring container. After loading the currencyconverter.xml file into
the container, the main() method calls the getBean() method on the BeanFactory to retrieve a reference to
the CurrencyConverter service. With this reference in hand, it finally calls the dollarsToRupees() method.
When we run the above application (CurrencyConverterClient.java), output is as seen in Figure 1.1 in
Appendix B.
This example illustrates the basics of configuring and using a class in Spring. It is simple because it only
illustrates how to configure a bean by injecting a double value into a property. The real power of Spring lies
in how beans can be injected into other beans using IoC (Inversion of Control – to be discussed later).
In Java a class can have multiple constructors and thus you can program your bean classes
with constructors that take enough arguments to fully define the bean at instantiation. This
is done by having Spring set the exchangeRate property through currencyConverterImpl’s
single argument constructor. For Eg:
If a constructor has multiple arguments, then you can deal with ambiguities among
constructor arguments in two ways :
•by index
•by type.
The <constructor-arg> element has an optional index attribute that specifies the ordering of
the constructor arguments.
<constructor-arg index=”1”>
<value> some-value </value>
<constructor-arg>
The type attribute lets you specify exactly what type each argument is supposed to be.
<constructor-arg type=”java.lang.String”>
<value> some-value </value>
<constructor-arg>
The following code illustrates how the container will instantiate the CurrencyConverter
service when using the <constructor-arg> element using the same classes seen above.
Inversion of control
IoC introduces the concept of a framework of components that in turn has many similarites
to a J2EE container. The IoC framework seperates facilities that your components are
dependent upon and provides the “glue” for connecting the components.
The control of the facilities upon which your components depend is inverted so that external
frameworks can provide the facilities as transparently as possible. The IoC pattern formally
recognises the move from traditional components being responsible for the facilities upon
which they depend, to thoses facilities being configured and provided by a separate
framework.
The above figure shows some examples of the different component roles that make up the
IoC pattern
Inversion of control
The IoC pattern uses three different approaches to achieve this decoupling of control of services
from your components:
Type 1 : Interface injection: This is how most J2EE worked. Components are explicitly
conformed to a set of interfaces with associated configuration metadata, in order to allow
framework to manage them correctly.
Type 2 : Setter Injection: External metadata is used to configure how components can
interact. Our last example used this approach, by using a Springconfig.xml file.
Type 3 : Constructor injection: Components are registered with the framework, including the
parameters to be used when the components are constructed, and the framework provides
instances of the component with all the specified facilities applied.
Injecting dependencies:
In a article written in early 2004, Martin Fowler asked what aspect of control is being inverted.
He concluded that it is the acquisition of dependent objects that is being inverted. Based on
this he coined another term for IoC – the DI (dependency injection).
Any non-trivial application is made up of two or more classes that collaborate with each other
to perform some business logic. Traditionally, each object is responsible for obtaining its own
references to the objects it collaborates with (its dependencies). This can lead to a highly
coupled and hard-to-test code.
Applying IoC, objects are given their dependencies at creation time by some external entity that
coordinates each object in the system ie dependencies are injected into objects. So, IoC means
an inversion of responsibility with regard to how an object obtains references to collaborating
objects.
Bean containers
The BeanFactory
Lets start our exploration of Spring containers with the most basic of Spring containets : the
BeanFactory.
Bean factory is a class whose responsibility is to create and dispense beans. Since a bean
factory knows about many objects within an application, it is able to create associations
between collaborating objects as they are instantiated. This removes the burden of
configuration from the bean itself and the bean’s client. As a result, when a bean factory
hands out objects, those objects are fully configured, are aware of their collaborating
objects and are ready to use. Morever, a bean factory also takes part in the life cycle of a
bean, making calls to custom initialization and destruction methods, if those methods are
defined.
The XmlBeanFactory
or
ClassPathResource res = new ClassPathResource("beans.xml");
Among the many implementations of the bean factory, the most useful is the
org.Springframework.beans.factory.xml. The BeanFactory is instantiated via explicit user
code such as:
This simple line of code tells the bean factory to read the bean definitions from the XML file.
But the bean factory doesn’t instantiate the beans just yet. Beans are “lazily” instantiated
into bean factories, meaning that while the bean factory will immediately load the bean
definitions, beans themselves will not be instantiated until they are needed.
The XmlBeanFactory
To retrieve a bean from a bean factory, simply call the getBean() method, passing it the
name of the bean you want to retrieve.
MyBean myBean = (MyBean) factory.getBean("myBean");
When getBean() is called, the factory will instantiate the bean and begin setting the bean’s
properties using dependency injection. Thus begins the bean’s life cycle within the container
(explained further on).
A BeanFactory configuration consists of, at its most basic level, definitions of one or more
beans that the BeanFactory must manage. In an XmlBeanFactory, these are configured as one
or more bean elements inside a top-level beans element.
Wiring Beans
Coupling is a two headed beast. On one hand, tightly coupled code is difficult to test,
difficult to reuse, difficult to understand. On the other hand, completely uncoupled code
doesn’t do anything. In order to do anything useful, classes need to know about each other
somehow. Coupling is necessary but it must be managed very carefully. A common technique
used to reduce coupling is to hide implementation details behind interfaces so that actual
implementation class can be swapped out without impacting the client class.
That is what IoC is all about: the responsibility of coordinating collaboration between
dependent objects is transferred away from the objects themselves. This is where
lightweight framework containers like Spring come into play.
The act of creating associations between application components is referred to as wiring. In
Spring there are many ways of wiring components together, but most common is to use XML.
(currencyconverter4.xml). The <ref> subelement of the <property> lets us set properties that
reference other beans.
Demo : Example 4
In this Spring application, a BeanFactory loads the bean definition and wires the beans
together. The listing CurrencyConverterClient4.java uses an XmlBeanFactory to load
currencyconverter4.xml and to get a reference to the CurrencyConverter object. It then
simply invokes the dollarsToRupees() method.
Prototyping Vs Singleton
For most users, the majority of the beans in the container will be singletons. When a singleton
bean needs to collaborate with (use) another singleton bean, or a non-singleton bean needs to
collaborate with another non-singleton bean, the typical and common approach of handling this
dependency by defining one bean to be a property of the other, is quite adequate. There is
however a problem when the bean lifecycles are different. Consider a singleton bean A which
needs to use a non-singleton (prototype) bean B, perhaps on each method invocation on A. The
container will only create the singleton bean A once, and thus only get the opportunity to set its
properties once. There is no opportunity for the container to provide bean A with a new instance
of bean B every time one is needed.
One solution to this problem is to forgo some inversion of control. Bean A can be aware of the
container by implementing BeanFactoryAware, and use programmatic means (XmlBeanFactory in
client class) to ask the container via a getBean("B") call for (a new) bean B every time it needs it.
This is generally not a desirable solution since the bean code is then aware of and coupled to
Spring.
You would need to create a prototype bean ie instead of defining a single bean, you define a
blueprint. Beans are created based on this blueprint. This is achieved through the singleton
property of <bean>. Setting it to false results in bean being defined as a prototype. By default
this property is true.
Prototyped beans are useful when you want the container to give a unique instance of a bean
each time it is asked for, but you still want ot configure one or more properties of the bean
through Spring. Thus a new instance is created when getBean() is invoked with the bean’s name.
Method Injection, an advanced feature of the BeanFactory, allows this use case to be
handled in a clean fashion, along with some other scenarios.
If the method is not abstract, Spring will simply override the existing
implementation. In the XmlBeanFactory case, you instruct Spring to inject/override this
method to return a particular bean from the container, by using the lookup-method element
inside the bean definition. For example:
Demo : Example 5
In the last example (Ex-4), we had two beans, but both were instantiated only once ie
they were singleton beans. In example 5, we have a Stock service (StockService.java and
StockServiceImpl.java) that returns the exchange rate. CurrencyServiceImpl.java
retrieves the exchange rate from stock service and converts currency. The
currencyconverter5.xml sets the singleton attribute to false for the stock service. This
each time getBean() is invoked in CurrencyServiceClient.java, a new instance of stock
service is invoked.
Inner beans
Another lesser-used means of wiring bean references is to embed a <bean> element directly
in the <property> element. See currencyconverter4a.xml below:
The drawback of using this method is that you cannot reuse the instance of
ExchangeServiceImpl anywhere else – it is an instance created specifically for use by the
currencyConverter bean.
Autowiring
• byType
• constructor
• Autodetect
• Example 6
So far, you have seen how to wire all your bean’s properties explicitly using the <property>
element. Alternatively, you can also have Spring wire them automatically by setting the
autowire property on each <bean> that you want autowired.
<bean if=”foo” class=”com.Springinaction.Foo” autowire=”autowire type” />
There are four types of autowiring:
1.byName: Attempts to find a bean in the container whose name (or id) is same as the name
of the property being wired. If matching bean not found, property will remain unwired.
2.byType: Attempts to find a single bean in the container whose type is same as the name of
the property being wired.
3.constructor : 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 ambigous beans or ambigous
constructors, an org.Springframework.beans.factory.UnsatisfiedDependencyException will be
thrown.
For example, the declaration of the courseService bean when explictly wired looks like this:
By using byName, you are telling the container to consider all properties of the
CourseServiceImpl and look for beans declared with the same name as the property. In this
case, two properties, courseDAO and studentService, are eligible for autowiring through
setter injection. If beans are declared in the wiring file with the names courseDAO and
studentService, those beans will be wired to courseDAO and studentService resp.
Demo : Example 6
Refer to example 6. This uses the same exchange service and currency converter service
seen in earlier examples. However, by using the autowire attribute in the
currencyconverter6.xml we can execute the client program even without specifying the
exchange service.
<beans>
<bean id="exchangeService" class="training.spring.ExchangeServiceImpl" />
<bean id="currencyConverter" class="training.spring.CurrencyConverterImpl4“
autowire="byName" />
</beans>
In a traditional Java application, the life cycle of a bean is fairly simple. Java’s new keyword is
used to instantiate the bean and it is ready to use. In contrast, the life cycle of a bean within a
Spring container is a bit more elaborate.
A bean factory performs several setup steps before a bean is ready to use.
1.The container finds the bean’s definition and instantiates the bean.
2.Using dependency injection, Spring populates all the properties as specified in the bean
definition.
3.If the bean implements the BeanNameAware interface, the factory calls setBeanName() passing
the bean’s ID.
4.If the bean implements the BeanFactoryAware interface, the factory calls setBeanFactory()
passing an instance of itself.
5.If there are any BeanPostProcessers associated with the bean, their
PostProcessBeforeInitialization() methods will be called.
6.If an init-method is specified for the bean, it will be called.
7.Finally, if there are any BeanPostProcessers associated with the bean, their
PostProcessAfterInitialization() methods will be called.
At this point the bean is ready to be used and will remain in the bean factory until it is no longer
needed. It is removed from the factory in two ways:
1.If the bean implements the DisposableBean interface, the destroy() method is called.
2.If a custom destroy-method is specified, it will be called.
When a bean is instantiated, it may be necessary to perform some initialization to get it to a usable
state. Likewise when the bean is no longer needed and is removed from the container, some cleanup
may be in order. Thus, Spring can use two life-cycle methods of each bean to perform this setup and
teardown.
Declaring a custom init-method in your bean’s definition specifies a method that is to be called on the
bean immediately upon instantiation. Similarly, a custom destroy-method specifies a method that is
called just before a bean is removed from the container.
Among the many implementations of the application context, three most commanly used
ones are :
ClassPathXmlApplicationContext : Loads context definition from a XML file located in the
class path.
FileSystemApplicationContext: Loads context definition from an XML file in the file system.
XmlWebApplicationContext : Loads context definition from an XML file contained within a
web application.
Loading an application context from the file system or class path is similar to loading beans
into a bean factory.Eg: to load a FileSystemApplicationContext :
ApplicationContext context = new FileSystemApplicationContext(“c:/foo.xml”);
To load an application context from within the application’s class path using
ClassPathXmlApplicationContext :
ApplicationContext context = new ClassPathXmlApplicationContext(“foo.xml”);
The difference between the two is that FileSystemApplicationContext will look for foo.xml in
a specific location, whereas ClassPathXmlApplicationContext will look for foo.xml anywhere
in the class path.
In either case, you would retrieve a bean from an ApplicationContext just as you would from
a BeanFactory; by using the getBean() method, since ApplicationContext interface extends
the BeanFactory interface.
A difference between the two interfaces is how singleton beans are loaded. A bean factory
“lazily” loads all beans, deferring bean creation until getBean() is invoked. An
ApplicationContext preloads all singleton beans upon context startup. By preloading
singleton beans, you ensure that they will be ready to use when needed.
The life cycle of a bean within a Spring ApplicationContext differs only slightly from that of a
bean within a bean factory as shown in above figure.
The only difference is that if a bean implements the ApplicationContextAware interface, the
setApplicationContext() method is invoked.
• postProcessAfterInitialization
Until now, we have seen how to define beans within the Spring container and how to wire them
together. But if you look at the lifecycle’s of both, the BeanFactory and ApplicationContext, you
will notice opportunities to cut into the bean’s life cycle and review or alter its configuration. This
is called post processing and occurs after some event has occurred. A bean post-processor is a java
class which implements the BeanPostProcessor interface, which consists of two callback methods:
1. postProcessBeforeInitialization : called immediately before bean Initialization.
2. postProcessAfterInitialization : called immediately after bean Initialization.
An ApplicationContext will automatically detect any beans which are deployed into it which
implement the BeanPostProcessor interface, and register them as post-processors, to be then called
appropriately by the factory on bean creation. Nothing else needs to be done other than deploying
the post-processor in a similar fashion to any other bean. On the other hand, when using plain
BeanFactories, bean post-processors have to manually be explicitly registered, with a code
sequence such as the following:
ConfigurableBeanFactory bf = new .....; // create BeanFactory
... // now register some beans
…… // now register any needed BeanPostProcessors
MyBeanPostProcessor pp = new MyBeanPostProcessor();
bf.addBeanPostProcessor(pp); // now start using the factory ...
Since this manual registration step is not convenient, and ApplictionContexts are functionally
supersets of BeanFactories, it is generally recommended that ApplicationContext variants are used
when bean post-processors are needed.
BeanPostProcessors cont.
Lets take a look at how you can use the PropertyPlaceholderConfigurer implementation of
BeanFactoryPostProcessor.
PropertyPlaceholderConfigurer
<bean id="placeHolderConfig"
class=“…….PropertyPlaceholderConfigurer">
<property name="location"><value>user.properties</value>
</property> </bean>
user.java user.properties
user.xml UserClient.java
user2.properties
Copyright © 2006 by Patni
For the most part, it is possible to configure entire application in a single bean wiring file.
But sometimes its beneficial to extract certain pieces of that configuration into a separate
property file.
Eg :, lets say you want to configure a data source with the following XML in the bean wiring
file.
Configuring the data source directly in the bean wiring file may not be appropriate. The
database specifics are a deployment detail. Conversely, the purpose of the bean wiring file
is mainly oriented toward defining how components within your application are put together.
But deployment details must be separated.
Fortunately, externalizing properties in Spring is easy if you are using ApplicationContext as
your Spring container. You can use PropertyPlaceholderConfigurer to tell Spring to load
certain configuration from an external property file. To enable this, configure the following
bean wiring file:
<bean id="placeHolderConfig"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location">
<value>user.properties</value>
</property>
</bean>
The location property tells Spring where to find the property file.
Please refer to example 7. In this case user.java is a POJO with setter and getter methods.
user.properties is a properties file with two properties.
user.xml has two place holder variables ${username} and ${password} . Whenever setter is
called, the listener (PropertyPlaceholderConfigurer) is invoked and it will look into the
properties file, retrieve values, place them in the place holders and initialize.
If instead of application context, bean factory is used, then the listener would have to be
explicitly registered as shown in the commented out code in userClient.java file.
Please refer to example 7’s user2.properties file. Now in the userClient.java file, the
getBean() method as getBean(“user2”) . The application will retrieve name from
user2.properties.
CustomEditorConfigurer
If an attempt is made to set a non-string property to a string value, the setAsText() method
is called to perform the conversion. Likewise, the getAsText() is called to return a textual
representation of the property’s value.
Spring comes with several custom editors based on PropertyEditorSupport. You can also write
your own custom editor by extending the PropertyEditorSupport class.
Please refer to example 8. The Employee.java is a POJO that holds the date property. Using
basic wiring techniques learnt so far, you could set a value into Employee beans’ date
property. But we have SQLDateEditor.java extending PropertyEditorSupport class.
Now we need Spring to recognize your custom property editor when wiring bean properties.
For that , we will need to use Spring’s CustomEditorConfigurer. This is a
BeanFactoryPostProcesser that loads custom editors into the BeanFactory by calling the
registerCustomEditor() method. By adding the following bit of XML into the bean
configuration file, you will tell Spring to register the SQLDateEditor as a custom editor.
<bean id="customEditorConfigurer"
class="org.springframework.beans.factory.config.CustomEditorConfigurer">
<property name="customEditors">
<map>
<entry key="java.sql.Date">
<bean class="training.spring.SQLDateEditor" />
</entry>
</map>
</property>
</bean>
You will now be able to configure the Employee objects date property using a simple string
value:
Note that many of the custom editors that come with spring are already registered with the
bean factory upon container startup. You need not register tham explicitly using
CustomEditorConfigurer.
Many times you may not want to hard-code certain text that will be displayed to the user of
the application. This may be because text is subject to change or perhaps your application
will be internationalized and you will display text in the user’s native language.
Java’s support for parameterization and internationalization of messages enables you to
define one or more properties files that contain the text that is to be displayed in your
application. There should always be a default message file along with optional language-
specific message files. For ex : if name of the application’s message bundle is “MsgText”,
you may have the following set of message property files:
<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basename"><value>applicationResources</value></property>
</bean>
It is very important that this bean be named messageSource because the ApplicationContext
will look for a bean specifically by that name when setting up its internal message source.
You will never need to inject the messageSource bean into your application bean’s but will
instead access messages via ApplicationContext’s own getMessage() methods. For eg to
retrieve the message whose name is computer, use this code:
But if you need your bean’s and not JSP to retrieve the messages, you need to make your
beans aware of their container, through the BeanNameAware, BeanFactoryAware and
ApplicationContextAware interfaces.
AOP : An introduction
Aspect-Oriented Programming has at its core the enabling of a better separation of concerns,
by allowing the programmer to create cross-cutting concerns as first-class program modules.
For example, consider a banking application with a conceptually very simple method for
transferring an amount from one account to another:
However, in a real-world banking application, this transfer method seems far from adequate.
We must include security checks to verify that the current user has the authorization to
perform this operation. We must enclose the operation in a database transaction in order to
prevent accidental data loss. We must log the operation to the system log. And so on. A very
simplified version with all those new concerns would look somewhat like this:
The code has lost its elegance and simplicity because the various new concerns have become
tangled with the basic functionality. The transactions, security, logging, etc. all exemplify
cross-cutting concerns.
Also consider what happens if we suddenly need to change (for example) the security
considerations for the application. In the program's current version, security-related
operations appear scattered across numerous methods, and such a change would require a
major effort.
Therefore, we find that unlike the core concerns of the system, the cross-cutting concerns
do not get properly encapsulated in their own modules. This increases the system complexity
and makes maintenance considerably more difficult.
AOP attempts to solve this problem by allowing the programmer to develop cross-cutting
concerns as full stand-alone modules called aspects.
Introducing AOP:
Aspect Oriented programming is often defined as a programming technique that promotes
separation of concerns within a software system. Systems are composed of several
components, each responsible for a specific piece of functionality. Often, however, these
components also carry additional responsibility beyond their core functionality. System
services like logging, transaction management and security often find their way into
components whose core responsibility is something else. These system services are commonly
referred to as cross-cutting concerns because they tend to cut across multiple components in
a system.
By spreading these concerns across multiple components, you introduce two levels of
complexity to your code:
1.The code that implements the systemwide concerns is duplicated across multiple
components. This means that if you need to change how these concerns work, you will need
to visit multiple components.
2.Your components are littered with code that isn’t aligned with their core functionality. A
method to add an entry to an address book should only be concerned with how to add the
address and not whether it is secure or transactional.
AOP makes it possible to modularize services and then apply them declaratively to the
components that they should affect. This results in components that are more cohesive and
that focus on their own specific concerns, completely ignorant of any system services that
may be involved.
AOP contd…
It may help to think of aspects as blankets that cover many components of an application. At
its core, an application is comprised of modules that implement the business functionality.
With AOP, you can then cover your core application with layers of functionality. These layers
can declaratively be applied throughout your application in a flexible manner without your
core application even knowing they exist. This is a very powerful concept.
The above figure represents a typical application that is broken down into modules. Each
module’s main concern is to provide services for its particular domain. However, each of
these modules also requires similar support functionalities such as security and transaction
management. The common object-oriented technique of reusing common functionality is
through inheritance or delegation. But inheritance can lead to a brittle object hierarchy if
the same base class is used throughout an application and delegation can be cumbersome
and still requires duplicated calls to the delegate object.
AOP presents an alternative that can be cleaner in many circumstances. With AOP, you can
still define the common functionality in one place, but you can declaratively define how and
where this functionality is applied without having to modify the class to which you are
applying the new feature. Cross-cutting concerns can now be modularized into special
objects called aspects. This has two benefits:
1.Logic for each concern is now in one place, as opposed to being scattered all over the code
base.
2.Service modules are now cleaner since they only contain code fro their core functionality
and secondary concerns have been moved to aspects.
AOP terminology
1. Aspect
2. Advice
3. Join-point
4. Point-cut
Cross-cutting concerns: Even though most classes in an OO model will perform a single,
specific function, they often share common, secondary requirements with other classes. For
example, we may want to add logging to classes within the data-access layer and also to
classes in the UI layer whenever a thread enters or exits a method. Even though the primary
functionality of each class is very different, the code needed to perform the secondary
functionality is often identical.
Aspect : an aspect is the cross-cutting functionality you are implementing ie. the area of
your application you are modularizing. A simple example is logging, which is required
throughout an application. However, because applications tend to be broken down into
layers based on functionality, reusing a logging module through inheritance does not make
sense. However, you can create a logging aspect and apply it throughout your application
using AOP.
Joinpoint: this is a point in the execution of the application where an aspect can be plugged
in. This point could be a method being called, an exception being thrown or even a field
being modified. These are points where your aspect’s code can be inserted into the normal
flow of your application to add new behavior.
Advice: this is the actual implementation of aspect. It is advising your application of new
behavior. For example, logging advice would contain the code that implements the actual
logging such as writing to a log file. Advice is inserted into our application at joinpoints.
Point-cut: a pointcut defines at what joinpoints advice should be applied. Advice can be
applied at any joinpoint supported by the AOP framework. For example, a point-cut is
reached when the thread enters a method, and another point-cut is reached when the
thread exits the method. You may not want to apply all aspects at all join-points. Point-cuts
allow you to specify where you want advice to be applied.
In the above figure, the advice contains the cross-cutting behavior that needs to be applied.
The join-points are all the points within the execution flow of the application that are
candidates to have advice applied. The point-cut defines at what join-points that advice is
applied. Key concept from this is : Point-cuts define which join-points get advised.
One of the key components of Spring is the AOP framework. While the Spring IoC containers
(BeanFactory and ApplicationContext) do not depend on AOP, meaning you don't need to use
AOP if you don't want to, AOP complements Spring IoC to provide a very capable middleware
solution.
AOP in Spring: Aspects are implemented using Spring as Advisors or interceptors. In Spring
AOP, a joinpoint is always method invocation. Advice contains the logic of your aspect. So
when you create an advice object, you are writing the code that implements the cross-
cutting functionality. Spring’s join-point model is built around method interception. This
means that the Spring advice will be woven into the application at different points around a
method’s invocation. Since there are several points during the execution of a method, there
are several advice types:
Before advice: Called before target method is invoked. Advice that executes before a
joinpoint, but which does not have the ability to prevent execution flow proceeding to the
joinpoint (unless it throws an exception). To accomplish this, we must implement the
before() method of the org.springframework.aop.MethodBeforeAdvice interface.
After advice: Called after the target method returns. Advice to be executed after a
joinpoint completes normally. For example, if a method returns without throwing an
exception. To accomplish this, we must implement the afterReturning() method of the
AfterReturningAdvice interface.
Around advice: Advice that surrounds a joinpoint such as a method invocation and intercepts
calls to target method. This is the most powerful kind of advice. Around advices will perform
custom behavior before and after the method invocation. They are responsible for choosing
whether to proceed to the joinpoint or to shortcut executing by returning their own return
value or throwing an exception. To accomplish this, we must implement the invoke() method
of the MethodInterceptor interaface.
Defining point-cuts: although we have seen how to write advice, we still need to define
where this advice should be applied in our application. Spring defines point-cuts in terns of
the class and method that is being advised. The core interface is Pointcut.
public interface Pointcut {
ClassFilter getClassFilter();
MethodMatcher getMethodMatcher();
}
The ClassFilter interface determines if a class is eligible for advising. If the matches()
method always returns true, all target classes will be matched:
public interface ClassFilter {
boolean matches(Class clazz);
}
The ClassFilter lets you filter your aspects by class, but the MethodMatcher interface filters
by methods:
public interface MethodMatcher {
boolean matches(Method m, Class targetClass);
boolean isRuntime();
boolean matches(Method m, Class targetClass, Object[] args);
}
ProxyFactoryBean
target Target bean for the proxy
If you're using the Spring IoC container for your business objects you will want to use one of
Spring's AOP FactoryBeans. Please note that we have seen several examples where client has
directly invoked a beans’ methods. However, if there are some interceptor activities to be
done, you use a proxy via XML configuration. The ProxyFactoryBean class is a central class
for explicitly creating proxied objects within the BeanFactory. You can give it an interface to
implement, a target object to proxy and advice to weave in and it will create a brand new
proxied object.
Target: property defines what bean should be the target object of the generated proxy
object. This is the object being advised. For ex:
<bean id="businessLogicBean“
class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces">
<value>training.spring.IBusinessLogic</value>
</property>
<property name="target">
<ref local="beanObject"/>
</property>
<bean id="beanObject" class="training.spring.BusinessLogic"/>
The interceptorNames property : is a list of advice bean names that should be applied to
the target bean. The ordering of this list is important as this dictates the order in which the
advice will be applied. For eg:
<property name="interceptorNames">
<list>
<value>tracingBeforeAdvisor</value>
<value>tracingAfterAdvisor</value>
<value>tracingThrowsAdvisor</value>
<value>tracingAroundAdvisor</value>
</list>
</property>
Autoproxying
Example 10:
iBusinessLogic.java
BusinessLogic.java
BusinessLogicException.java
TracingAfterAdvice.java
aop.xml
Copyright © 2006 by Patni
Please refer to the figure in the above slide. Client calls a method say abc() in bean. But the
control first goes to proxy which in turn applies advices to the target method.
Autoproxying
Autoproxying:
So far, we have created our proxy objects using the ProxyFactoryBean class. This is fine with
small applications, since there are not that many classes we want to advise. But when we
have sevaral classes to advise, it becomes cumbersome to explicitly create every proxy.
To this end, Spring has an autoproxing facility that enables the container to generate proxies
for us by configuring a bean. Spring gives two classes that provide this support:
•BeanNAmeAutoProxyCreator : generates proxies for beans that match a set of names.
•DefaultAdvisorAutoProxyCreator : is more powerful. To use this class, include it as a bean
in the BeanFactory configuration. The magic of this class lies within its implementation of
the BeanPostProcesser interface. After your beans definitions have been read in by the
ApplicationContext, the DefaultAdvisorAutoProxyCreator scours the context for any advisors.
It then applies these advisors to any beans that match the advisors point-cut. Note that this
proxy creator works only with advisors.
In the xml code snippet below, we have applied a interceptor to all our service objects.
When all of the bean definitions are read in, all the advisors in the BeanFactory will be cut
loose, so that they can apply their advise to any beans that match their point-cuts. This
allows you to raelly flex the poswer of point-cuts. Instead of having to explicitly associate
your advisors with anything, you can simply define them and have them automatically
applied to any bean thay are configured to match. This is where the loose coupling of beans
and their advise is really achieved; you write your beans and the container plays
matchmaker!
<bean id="tracingBeforeAdvisor“
class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<property name="advice">
<ref local="beforeAdvice" />
</property>
<property name="pattern">
<value>.*</value>
</property>
</bean>
……..
<bean id="beforeAdvice" class="training.spring.TracingBeforeAdvice" />
Demo : Example 10
Summary :
Spring JDBC
DAO support
Spring’s DAO philosophy: One of Spring’s goals is to let you develop applications, following the
OO principle of coding.
DAO (data access object) provides a means to read and write data to the database and exposes
this functionality through an interface by which rest of application will access them. Advantage is
that it makes your service objects easily testable, since they are not coupled to a specific
database implementation.
To make it easier to work with a variety of data access technologies like JDBC, JDO and Hibernate
in a consistent way, Spring provides a set of abstract DAO classes that you can extend. These
abstract classes has methods for setting the data source and any other configuration settings that
are specific to the technology you currently are using.
JdbcTemplate interface
The JdbcTemplate is the most important class of the operations. It executes the core JDBC
workflow like statement creation and execution, leaving application code to provide SQL and
extract results. This class executes SQL queries, update statements or stored procedure
calls, imitating iteration over ResultSets and extraction of returned parameter values. It also
catches JDBC exceptions and translates them to the generic, more informative, exception
hierarchy defined in the org.springframework.dao package.
In order to work with data from a database, we need to obtain a connection to the database.
The way Spring does this is through a DataSource. When using Spring's JDBC layer, you can
either obtain a data source from JNDI or you can configure your own, using an
implementation that is provided in the Spring distribution.
Executing Statements
• To execute an SQL statement all you need is a DataSource and a
JdbcTemplate. Eg:
import javax.sql.DataSource;
import org.springframework.jdbc.core.JdbcTemplate;
public class ExecuteAStatement {
private JdbcTemplate jt; private DataSource dataSource;
public void doExecute() {
jt = new JdbcTemplate(dataSource);
jt.execute("create table mytable (id integer, name varchar(100))"); }
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource; }}
Executing Statements :
To execute an SQL statement, there is very little code needed. All you need is a DataSource
and a JdbcTemplate. You can then use a number of convenience methods that are provided
with the JdbcTemplate.
The following example shows code to include for a minimal but fully functional class that
creates a new table:
import javax.sql.DataSource;
import org.springframework.jdbc.core.JdbcTemplate;
The dataSource could be injected into the code or programmatically created. Similarly the
JdbcTemplate can also be configured in the context.xml file:
In addition to the execute methods, there are a large number of query methods. Some of
these methods are intended to be used for queries that return a single value. Maybe you
want to retrieve a count or a specific value from one row. If that is the case then you can
use queryForInt(), queryForLong() or queryForObject(). The latter will convert the returned
JDBC Type to the Java class that is passed in as an argument. If the type conversion is
invalid, then an InvalidDataAccessApiUsageException will be thrown. Here is an example that
contains two query methods, one for an int and one that queries for a String.
In addition to the single results query methods there are several methods that return a List
with an entry for each row that the query returned. The most generic one is queryForList()
which returns a List where each entry is a Map with each entry in the map representing the
column value for that row.
For example to retrieve a list of all the rows, it would look like this:
The list returned would look something like this: [{name=Bob, id=1}, {name=Mary, id=2}].
Another example:
Object params[] = new Object[]{new Double(1000.0)};
List rows1 = jt.queryForList(“Select * from emp where sal > ?”, params);
There are a couple of points that you should notice about this example. First, we have to
supply the SqlUpdate object with a DataSource. It uses this to create a JdbcTemplate.
Second, notice the declareParameter() calls, which is required for each of the parameters in
our statement. The order is important: they must be issued in the same order that they
appear in the SQL. Every database operation object must be compiled before it is used. By
including compile() at the end of the constructor, we ensure that this happens. Notice also
that we have not used a single JDBC API and there is no reference to a preparedStatement or
Connection object.
Using RowCallbackHandler
• The RowCallbackHandler is a callback interface used by
JdbcTemplate's query methods
Using RowCallbackHandler:
JdbcTemplate class supports the callback methods concept for performing different SQL
operations. Callback methods allow the developer to manage database operations using a
higher level of abstraction. The RowCallbackHandler is a callback interface used by
JdbcTemplate's query methods. Implementations of this interface perform the actual work of
extracting results, but don't need to worry about exception handling. A RowCallbackHandler
object is typically stateful: It keeps the result state within the object, to be available for
later inspection.
But please note that any processing done here will not affect the final objects in the list. If
processed information must go into list, then we need to use the ResultReader class. We will
see an example after we see the PreparedStatementSetter.
PreparedStatementSetter interface
Using PreparedStatementSetter:
This interface sets values on a PreparedStatement provided by the JdbcTemplate class.
Implementations are responsible for setting any necessary parameters. SQL with placeholders will
already have been supplied. Has a single method setValues(PreparedStatement), which sets values
on the given PreparedStatement. See the code below for an example. The query() method of the
JdbcTemplate queries using a prepared statement. The third argument of this method uses the
ResultReader which first processes each row of data in the ResultSet. The getResults() returns all
results, disconnected from the JDBC ResultSet.
Using MappingSqlQuery
Using MappingSqlQuery:
Mapping JDBC operations to domain objects is a very common requirement. MappingSqlQuery is
a reusable query in which concrete subclasses must implement the abstract
mapRow(ResultSet, int) method to convert each row of the JDBC ResultSet into an object. Of
all the SqlQuery implementations, this is the one used most often and it is also the one that is
the easiest to use.
Here is a brief example of a custom query that maps the data from the emp table to a Java
object called emp
EmployeeQuery(DataSource ds) {
super(ds, sql);
super. declareParameter(new SqlParameter(“sal”,Types.DOUBLE));
compile();
}
public Object mapRow(ResultSet rs, int index) throws SQLException {
Employee emp = new Employee();
emp.setEmpno(rs.getInt(1));
emp.setName(rs.getString(2));
return emp;
}
}
We provide a constructor for this emp query that takes the DataSource as the only
parameter. In this constructor we call the constructor on the superclass with the DataSource
and the SQL that should be executed to retrieve the rows for this query. This SQL will be
used to create a PreparedStatement so it may contain place holders for any parameters to
be passed in during execution. Each parameter must be declared using the declareParameter
method passing in an SqlParameter. The SqlParameter takes a name and the JDBC type as
defined in java.sql.Types. After all parameters have been defined we call the compile
method so the statement can be prepared and later be executed.
The method in this example retrieves the emp with the salary that is passed in as the only
parameter. We get a List that contains a emp object for each row that was returned for our
query. Every row returned becomes a domain object. Therefore List contains a list of emp
objects. But many users are not comfortable using a separate class for query. So we can use
JdbcTemplate class as shown in below code.
JDBC example
Example 11:
EmployeeDAO.java emp.java
EmployeeJdbcDAO.java EmployeeService.java
EmployeeServiceImpl.java emp2.xml
EmpClient2.java
Introduction:
As applications grow larger and more complex, JDBC becomes cumbersome to use. We need
to be able to map object properties to database columns and have our statements and
queries created for us, freeing us from typing an endless string of question marks. We also
need more sophisticated features like:
1.Lazy loading: As our object graphs become more complex, we sometimes don’t want to
fetch entire relationships immediately. Lazy loading allows us to grab data only as it is
needed.
2.Eager fetching: This is the opposite of lazy loading. Eager fetching allows to grab an entire
object graph in one query, saving us from costly round trips.
3.Caching : For data that is mostly read-only, we don’t want to fetch from database every
time it is used. Caching gives a significant performance boost.
4.Cascading: Sometimes a change to a table should result in changes to other tables as well.
This is a cascading effect.
There are many frameworks that provide these services. The general term for these services
are ORM (Object/Relational mapping). Using a ORM tool for your persistent layer can save a
lot of time and effort. This lets you switch from a error-prone SQL code to addressing your
application requirements. Spring provides integration for JDO (Sun’s standard persistence
API) as well as open source frameworks like Hibernate, Apache OJB and iBATIS SQL Maps. The
ORM tool does most of the actual persistence, while Spring provides integration points to
these frameworks. Let us see Spring’s integration with Hibernate.
<bean id="exampleSessionFactory“
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource">
<ref local=“dataSource"/>
</property>
</bean>
Spring provides integration with Hibernate, JDO, Oracle TopLink, Apache OJB and iBATIS SQL
Maps in terms of resource management, DAO implementation support, and transaction
strategies. For Hibernate, there is first-class support with lots of IoC convenience features,
addressing many typical Hibernate integration issues. All of these support packages for O/R
mappers comply with Spring's generic transaction and DAO exception hierarchies. There are
usually two integration styles: either using Spring's DAO 'templates' or coding DAOs against
plain Hibernate/JDO/TopLink/etc APIs. In both cases, DAOs can be configured through
Dependency Injection and participate in Spring's resource and transaction management.
Hibernate overview:
Hibernate is a high performance, open source persistence framework that has gained
significant popularity. It not only provides basic ORM (Object/relational mapping), but also
all the other sophisticated features expected from a full-featured ORM tool like caching, lazy
loading, eager fetching and distributed caching.
Very little code is needed to execute this operation, because Hibernate is doing all the work
based on your mapping. Since Hibernate makes persistence easier, Spring focuses on making
it easier to integrate with Hibernate.
<bean id="exampleSessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
Of course the SessionFactory needs to know which database to connect. The preferred way
to do this is to wire a DataSource to the LocalSessionFactoryBean:
<bean id="exampleSessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource">
<ref local=“dataSource"/>
</property>
</bean>
You also manage how Hibernate is configured through the same LocalSessionFactoryBean
bean. Hibernate itself has many properties by which you can tweak its behavior. When used
outside of Spring, Hibernate looks for a file named hibernate.properties somewhere on the
application class path for its configurations. However, with Spring, you do not have to
manage these configurations in a separate properties file. Instead, you can wire them to the
hibernateproperties property of the LocalSessionFactoryBean:
<bean id="exampleHibernateProperties"
class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name=“hibernateproperties">
<props>
<prop key="hibernate.hbm2ddl.auto">create</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
</props>
</property>
</bean>
One last thing you must configure is which mapping file Hibernate should read in. For
example, if the Student.java has a corresponding Student.hbm.xml file, we need to tell
Hibernate it needs to use this file. Otherwise it would not know how to map Student class to
the database. Again, we can configure this through a property of the
LocalSessionFactoryBean bean. In this case, we use the mapping-resources property:
This example works just fine for small applications. But what if the application grows and you have many
persistent classes? It would be cumbersome to configure them all in this fashion. Spring gives an alternative.
You can also configure the mapping-DirectoryLocations property with a path that is a subset of the
application’s class path and Spring will configure the SessionFactory with every *.hbm.xml it finds in this
path. For example, assuming that all the persistence classes we want to configure are contained in the
com.spring.trg.model package, we would configure our SessionFactory like this:
Now we have a fully configured SessionFactory and we didn’t even need to create a second configuration
file. Now all we need to do is to create an object through which we will access Hibernate. Like all of
Spring’s DAO frameworks, this will be a template class. In this case, it is the HibernateTemplate class. And
because the class is thread-safe, we can share this template class with multiple DAO objects.
And remember, if it becomes cumbersome to wire the template into each of your DAO beans, you can always
use Spring’s autowire facility to implicitly wire your DAO beans. Now that you know how to wire a
HibernateTemplate to your DAO objects, we are ready to start using Hibernate.
Lets see the working of this mechanism, by first getting an object from the database:
Examples
Thus, we have benefits of having Spring managing our resources, converting proprietary
exceptions, adding transactions. This example is how Hibernate is accessed through the
Hibernate template is very popular. Another convenience method is update. For example, to
update a Student object:
Querying the database is also simple using the find method. For ex to query for students by
last name:
The convenience methods of the HibernateTemplate class are used to access data. To run
this example, please make appropriate changes to the data source properties in the spring-
hibernate.xml file.
As a J2EE developer, you may have developed a web-based application. There are a
number of challenges you may have faced like state management, workflow, validation
etc.
Spring’s web framework is designed to help you address these concerns. Using Spring, you
can leverage its web framework to automatically populate your model objects from
incoming request parameters while providing validation and error handling as well. You
can also rely on the framework to help manage the state of the object that is being
created by your users through web forms.
Additionally, the entire framework is modular, with each set of components having
specific roles and completely decoupled from the rest of the framework. This allows you
to develop the front end of your web application in a very pluggable manner.
The Spring MVC is a web framework built within the Spring Framework. There are a number
of challenges while creating a web-based application like state management, workflow and
validation, which are addressed by Spring’s web framework. This can be used to
automatically populate your model objects from incoming request parameters while
providing validation and error handling as well. The entire framework is very modular and
thus lets you develop the front end of your application in a pluggable manner.
The Spring MVC component that is responsible for handling the request is Controller. To
figure out which controller should handle the request, DispatcherServlet starts by querying
one or more HandlerMappings. A HandlerMapping typically performs its job by mapping URL
patterns to Controller objects. Once the DispatcherServlet has a Controller object, it
dispatches the request to the Controller to perform the business logic it was designed to do
(actually a well-designed Controllerobject performs little or no business logic itself and
delegates responsibility to one or more service objects). Upon completion of business logic,
the Controller returns a ModelAndView object to the DispatcherServlet. The ModelAndView
can either contain a View object or the logical name of a View object. If it is the latter, the
DispatcherServlet queries a ViewResolver to look upo the View object that will render the
response. Finally the DispatcherServlet dispatches the request to the View object, which is
responsible for rendering a response back to the client.
The following steps define the bare minimum that must be done to build the homepage in
Spring MVC:
1.Write the controller class that performs the logic behind the homepage (Example 14 :
BasicSpringController.java).
2.Configure the controller in the DispatcherServlet’s context configuration file (basicspring-
servlet.xml).
3.Configure a view resolver to tie the controller to the jsp.
4.Write the JSP that will render the homepage to the user.
Lets see these steps in detail with an example. Please refer to Example 14.
1. Write the controller class that performs the logic behind the homepage
(BasicSpringController.java).
In Spring MVC, the Controller is a class that is ultimately responsible for handling a request
and performing some processing on it. It is almost similar to an HttpServlet or the Struts
Action. In fact the Controller’s handleRequest() signature is almost similar to service()
method. However, the Spring MVC Controller is configured as just another JavaBean in the
Spring application context.
The handleRequest() returns a ModelAndView object. This is an object that holds both view
information and model data that will be used while rendering the output. In our example,
the ModelAndView returned tells DispatcherServlet to take the user to the view whose name
is hello and to place the now object into the “now” field of the model data.
ModelAndView("hello","now",now);
<bean id="basicspringController"
class="training.web.spring.BasicSpringController" />
<bean name="/hello.obj"
class="training.web.spring.BasicSpringController" />
Instead of specifying a bean id for the Controller bean, we can also use name. It would then
specify the name of bean and also the URL pattern for requests that should be handled by
this controller:
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass">
<value> org.springframework.web.servlet.view.JstlView
</value>
</property>
<property name="prefix">
<value>/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
Example 14 : hello.jsp
4. Write the JSP that will render the homepage to the user.
To run the program, please add ${now} or a <c:out> jstl tag to the hello.jsp page like this:
<html>
<body>
<h1>Welcome to Spring!!</h1>
Now it is ${now}
</body>
</html>
Now copy the ex14 folder as is into the webapps folder of Tomcat or web application folder
of any other web server. Invoke the hello.jsp page as :
http://<server-name>:8080/ex14/hello.obj
However, Spring gives many other handler mapping implementations to choose from. Our example uses
the SimpleUrlHandlerMapping, which maps controllers to URL’s using a property collection defined in
the context configuration file. It lets you map without having to name your beans in a special way.
Eg :
<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<!--<property name="order" value="2" />-->
<property name="mappings">
<props>
<prop key="/hello.obj">basicspringController</prop>
</props>
</property>
</bean>
Thus, if DispatcherServlet is the heart of the Spring MVC, then Controllers are the brains.
Controller receives requests from DispatcherServlet and performs some business
functionality on behalf of the user. You may compare Controller to Action class of JStruts or
WebWorks. But, Spring provides a rich controller hierarchy whose top level is the Controller
interface. Any class implementing this interface can be used to handle requests through the
Spring MVC framework.To create your own controller, you may extend any of the classes
lower in the hierarchy, which provide additional functionality beyond the basics. Spring’s
controller classes can be grouped into six categories.
1.Simple : This is extremely simple, providing little more functionality beyond the basics.
2.Throwaway : handles requests as commands, in a manner similar to WebWork actions.
3.Multi-Action : Application has several actions that perform similar or related logic.
4.Command : accepts one or more parameters from the request and binds them into an
object.
5.Form : application needs to display a entry form to the user and also process the data
entered into the form.
6.Wizard : Applications that have a multipage entry form that ultimately gets processed as a
single form.
It is beyond the scope of this syllabus to discuss all types of controllers. The following
examples use some of these.
ModelAndView class
Introducing ModelAndView :
This class represents an important concept in Spring MVC. Every controller must return a
ModelAndView. This class fully encapsulates the view and model data that is to be displayed
by the view. Eg:
ModelAndView("hello","now",now);
The first parameter is the logical name of a view component that will be used to display the
output from this controller. The next two parameters represent the model object that will
be passed to the view and its value.
To configure it in the context configuration file, use the following bean definition:
<bean id="productController" class="training.web.spring.ProductController">
<property name="productManager">
<ref bean="prodMan" />
</property>
</bean>
Notice that the productManager property is injected with a reference to the productManager
object which is declared in the configuration file.
Demo : Example 14
http://<server-name>:8080/ex14/products.obj
Form controllers have an added functionality to display a form when a HTTP GET request is
received and process the form when an HTTP POST is received. Moreover, if errors occur in
the form, controller will know to redisplay the form so that the user can correct the errors
and resubmit.
The formView property is the logical name of the view to display when the controller
receives a HTTP GET request or when any errors are encountered. The successView property
is the logical name of a view to display when the form has been submitted successfully. A
view resolver will use these values to locate the view object that will render the output to
the user.
To send data to be displayed by the view, you should override the doSubmit() method. It
returns a ModelAndView object. But so that you can configure its success view in the context
configuration file, you should call the getSuccessView() when setting the view's logical name.
When the controller calls a method on the command object, its important to ensure that all
the data in the command object is valid and complete. The
org.springframework.validation.validator interface accommodates validation for Spring MVC.
Its defined as follows:
The UserValidator.java (Example 14) implements this interface and the simple validation
tests for lengths of username and password. The rejectValue() of the Errors interface reject
the given field of the current object, using the given error description and also contains
default message as the third argument.
Eg :
if(user.getUsername().length() < 3)
errors.rejectValue("username","username.invalid","Please enter a valid username");
How does Spring know about this class? Please refer to the config file:
</c:forEach>
Now that you are handling requests and forwarding them to jsp’s, you will need to access the model
data in order to display it on the page. Spring provides a tag library for doing this. It allows to see
your command objects and their properties and also any error messages associated with these
properties.
You must first register the tag library (spring.tld) in your application, after placing it in the WEB-INF
directory:
<taglib>
<taglib-uri>/spring</taglib-uri>
<taglib-location>/WEB-INF/spring.tld</taglib-location>
</taglib>
The bind tag has one attribute path that indicates the bean or bean property being used. For
example to access the username property of the user object, you would set path attribute to
user.username. This is made available through a
org.springframework.web.servlet.support.BindStatus object that is placed in page scope with the
name status. This object has three properties that will be of use to you on a jsp page:
1.expression : The expression used to retrieve the property. For eg to retrieve the firstName of a
Student, the expression would have a value of firstName.
2.value: The value as a string of the property.If the property is not a string, it will be converted by
the PropertyEditor associated with the property.
3.errorMessages : An array of strings that are the error messages associated with this property.
In this example, path binds the user.username to the username property. The
"${status.value}“ binds input value to status value. Instead of <input type="text"
name="username" , we could have used expression as :
Doing so will allow Spring to automatically map the form input field to the User object when
the form is submitted. Using the value property as the value of the form element also has its
benefits. This property will display the current value of the field, which will likely be the
value of that property. However, this could also be a rejected value from a previous form
submission, such as a date String improperly formatted. This can be extremely useful so that
you can display rejected values to the user so that they can see what is wrong and correct it.
How will users know what was wrong? Through the errorMessages property!
You not not can bind error messages for each property, but also have the ability to bind to the
actual command objects and display all error messages associated with this object.
The above code snippet showed binding to a specific property. The code snippet below,
shows direct binding to out command object. This way we can iterate over every error
message associated with the command object.
Eg :
<c:forEach items=“${status.errorMessages}” var=“errMsg” >
<c:out value=“${errMsg}” /> <br>
</c:forEach>
Handling exceptions:
Summary:
The Spring Framework comes with a powerful and flexible web framework that is itself based
on Spring’s tenets of loose coupling, inversion of control and extensibility. At the beginning
of a request, Spring offers a variety of handler mappings that help to choose a controller to
process the request. You are given a choice to map URL’s to controllers based on the
controller bean’s name, a simple URL-to-controller mapping or source-level metadata.
To process a request, Spring provides a wide selection of controller classes with complexity
ranging from the very simple Controller interface all the way to the very powerful wizard
controller. This sets Spring apart from other MVC web frameworks such as Struts and
WebWork, where your choices are limited to only one or two Action classes.
On the return trip to the client, Spring’s MVC view resolvers let you choose a View to render
the results of the request as output to the user.
All in all, Spring MVC maintains a loose coupling between how a controller is chosen to
handle a request and how a view is chosen to display output. This is a powerful concept,
allowing you to min-n-match different Spring MVC components to build a web layer most
appropriate to your application.
Up till now, we have been assuming that you will be using Spring MVC framework to drive the
web layer of your applications. But what if you have already invested heavily in another
framework? Nevertheless, you would like to use Spring in the other layers of your application
to take advantage of its support for declarative transactions, AOP and IoC.
There are too many frameworks available today and it is beyond the scope of this course to
show integration with all these frameworks. However, we will see how to integrate Spring
with one of the more popular frameworks – Jstruts. Spring can be easily integrated into any
Java-based web framework.
Lets see both approaches. But regardless of which approach you take, you need to tell Struts
about your Spring context.
<plug-in
className="org.springframework.web.struts.ContextLoaderPlugIn">
<set-property property="contextConfigLocation" value="/WEB-
INF/xxx-servlet.xml"/>
</plug-in>
ContextLoaderPlugin :
In order for Struts to have access to Spring-managed beans, you will need to register a Struts
plug-in that is aware of the Spring application context. Add the following code to your struts-
config.xml to register the plug-in:
<plug-in className="org.springframework.web.struts.ContextLoaderPlugIn">
<set-property property="contextConfigLocation" value="/WEB-INF/action-servlet.xml"/>
</plug-in>
The ContextLoaderPlugin is a Struts 1.1+ plug-in that loads a Spring context file
(WebApplicationContext to be specific)
for the Struts ActionServlet. The default name of the context file is the name of the mapped
servlet, plus -servlet.xml. If ActionServlet is defined in web.xml as <servlet-
name>action</servlet-name>, the default is /WEB-INF/action-servlet.xml.
For Eg:
public class UserAction extends DispatchActionSupport {
public ActionForward execute(ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response)
throws Exception {
WebApplicationContext context = getWebApplicationContext();
UserManager mgr = (UserManager) context.getBean("userManager");
// talk to manager for business logic
return mapping.findForward("success");
}
}
The good thing about using this approach to Struts-Spring integration is that its very intutive.
Aside from extending ActionSupport and retrieving beans from the application context, you
are able to write and configure your Struts actions in much the same way as you would in a
non-Spring Struts application.
But this approach also has a negative side. Your action classes will directly use Spring
specific classes. This tightly couples your code with Spring, which may not be desirable. Also,
the action class is responsible for looking up references to Spring-managed beans. This is in
direct notion to IoC.
Delegating actions
Delegating actions:
Another approach to Struts-Spring integration is to write a Struts action that is nothing more than a proxy
to the real Struts action that is contained in the Spring application context.The proxy action will retrieve
the application context from the ContextLoaderPlugIn, look up the real Struts action from the context,
then delegate responsibility to the real Struts action.
One nice thing about this approach is that the only action that does anything Spring-specific is the proxy
action. The real actions can be written as just plain subclasses of org.apache.struts.action.Action. This
would normally be registered in struts-config.xml. But instead, we are going to register the proxy action.
Spring provides a proxy action in the org.springframework.web.struts.DelegatingActionProxy class. You
need to set this action up in struts-config.xml.
Now we need to register the action class itself. This is registered as a bean in Spring context configuration
file. For eg, to register a class called UserAction.java which extends Action:
Here the bean is named using the name attribute instead of id., because XML places restrictions on what
characters can appear in an id attribute and ‘/’ is invalid. The value in the name attribute must exactly
match the path attribute of the <action> in struts-config.xml. That is because DelegatingActionProxy will
use the value of the path attribute to look up the real action in the Spring context.
Please notice that the UserAction gets a reference to a UserManager service thru a setter injection. For
Spring, it is just another bean. Therefore you can use Spring’s IoC to wire service beans into the Struts
action.
The benefit of using DelegatingActionProxy is that you are able to write Struts actions that do not use
any Spring-specific classes. Also your Struts actions can take advantage of IoC to obtain references to
their collaborating objects. However, this approach is not entirely intuitive.
This tells Struts to automatically delegate action requests to Struts actions in a Spring context. This
enables you to declare Struts action in struts-config.xml with their real type:
<action path="/User"
type=“org.springframework.web.struts.DelegatingRequestProcessor “ />
When a request is received for /User, DelegatingRequestProcessor will automatically refer to the Spring
application context, looking for a bean named /User (which is presumed to be a Struts action class).
Spring includes subclasses for all of the standard Struts Actions - the Spring versions merely have Support
appended to the name:
1.ActionSupport,
2.DispatchActionSupport,
3.LookupDispatchActionSupport and
4.MappingDispatchActionSupport.
The recommended strategy is to use the approach that best suits your project. Subclassing makes your
code more readable, and you know exactly how your dependencies are resolved. However, using the
ContextLoaderPlugin allow you to easily add new dependencies in your context XML file. Either way,
Spring provides some nice options for integrating the two frameworks.
Please refer to Example 15. Copy this into the webapps folder of your web server. This is part of the case
study in the labbook.
•Spring provides a very clean division between controllers, JavaBean models, and views.
•Spring's MVC is very flexible. Unlike Struts, which forces your Action and Form objects into
concrete inheritance (thus taking away your single shot at concrete inheritance in Java), Spring
MVC is entirely based on interfaces. Furthermore, just about every part of the Spring MVC
framework is configurable via plugging in your own interface.
•Spring, like WebWork, provides interceptors as well as controllers, making it easy to factor out
behavior common to the handling of many requests.
•Spring MVC is truly view-agnostic. You don't get pushed to use JSP if you don't want to; you can
use Velocity, XLST or other view technologies. If you want to use a custom view mechanism - for
example, your own templating language - you can easily implement the Spring View interface to
integrate it.
•Spring Controllers are configured via IoC like any other objects. This makes them easy to test, and
beautifully integrated with other objects managed by Spring.
•Spring MVC web tiers are typically easier to test , due to the avoidance of forced concrete
inheritance and explicit dependence of controllers on the dispatcher servlet.
•The web tier becomes a thin layer on top of a business object layer. This encourages good
practice. Struts and other dedicated web frameworks leave you on your own in implementing your
business objects; Spring provides an integrated framework for all tiers of your application.
Remoting overview:
Most applications need to communicate with other systems and also access services
remotely. As a Java developer, several remoting technologies are available like:
1.RMI
2.Caucho’s Hessian and Burlap
3.Spring’s own HTTP invoker
4.EJB
5.Web services
Remoting is a conversation between a client application and a service. On the client end,
some functionality is required that isn’t in the scope of the application. So the
application reaches out to another system that can provide the functionality by exposing
it through a remote service.
Spring supports remoting for six different RPC models as mentioned above. Regardless of
which remoting model you choose, you will find that a common theme runs through
Spring’s support for each of these models. That means if you learn how to configure
Spring to work with one model, you will have a very low learning curve for any other
model.
Proxying EJB’s
However, it is important to note that using Spring does not prevent you from using EJBs. In
fact, Spring makes it much easier to access EJBs and implement EJBs and functionality within
them. Additionally, using Spring to access services provided by EJBs allows the
implementation of those services to later transparently be switched between local EJB,
remote EJB, or POJO (plain java object) variants, without the client code client code having
to be changed.
In this chapter, we look at how Spring can help you access and implement EJBs. Spring
provides particular value when accessing stateless session beans (SLSBs), so we'll begin by
discussing this.
Please recall how to access EJB’s in the traditional way. You need to look up the home
interface through JNDI. Once you have a reference to the home interface, you will need to
get a reference to EJB’s remote (or local) interface and call its business methods.
To avoid repeated low-level code, many EJB applications use the Service Locator and
Business Delegate patterns. These are better than spraying JNDI lookups throughout client
code, but their usual implementations have significant disadvantages.
For example:
•Typically code using EJBs depends on Service Locator or Business Delegate singletons,
making it hard to test
•In the case of the Service Locator pattern used without a Business Delegate, application
code still ends up having to invoke the create() method on an EJB home, and deal with the
resulting exceptions. Thus it remains tied to the EJB API and the complexity of the EJB
programming model.
•Implementing the Business Delegate pattern typically results in significant code duplication,
where we have to write numerous methods that simply call the same method on the EJB.
Morever, till now we have seen ways of injecting our application beans with the services
they need. Beans’ do not look up other beans; they are given to other beans. But, with
EJB’s, we are looking up a EJB via JNDI and its home interface, which does not fit in with
how the rest of the application is constructed!
The Spring approach is to allow the creation and use of proxy objects, normally configured
inside a Spring ApplicationContext or BeanFactory, which act as code-less business
delegates. You do not need to write another Service Locator, another JNDI lookup, or
duplicate methods in a hand-coded Business Delegate unless you’re adding real value.
Proxying EJB’s:
Spring provides two proxy factory beans that proxy access to EJB’s:
1.LocalStatelessSessionProxyFactoryBean : Used to access local EJB’s (EJB’s in the same
container as their clients).
2.SimpleRemoteStatelessSessionProxyFactoryBean : Used to access remote EJB’s(Running in
a separate container)
Proxying EJB’s
<bean id="currencyService"
class="org.springframework.ejb.access.LocalStatelessSessionProxyFactoryBean">
<property name="jndiName" value="CurrencyConverterLocal" />
<property name="resourceRef" value="true" />
<property name="businessInterface"
value="com.CurrencyConversion.CurrencyService" />
</bean>
<bean id="currencyService"
class="org.springframework.ejb.access.LocalStatelessSessionProxyFactoryBean“
lazy-init=“true” >
<bean id=“someService”
class=“com.patni.SomeServiceImpl” >
<property name=“currencyService” >
<ref bean=“currencyService” />
</property>
…
</bean>
This is important when either of the EJB-loading proxy factory beans is used in an
ApplicationContext. This is because ApplicationContext-style bean factories pre-instantiate
singleton beans once the Spring configuration file is loaded. This is usually a good thing, but
it may result in the EJB proxy factory beans attempting to look up the EJB’s home interface
before the EJB is bound in the naming service. Setting lazy-init=“true” ensures that the
currencyService will not attempt to look up the home interface until it is first used – which
should give plenty of time for the EJB to be bound in the naming service.
The businessInterface property is equivalent to the serviceInterface property used with other
remote service proxy factory beans . It is set to com.CurrencyConversion.CurrencyService to
indicate that the service adheres to the currencyService interface.
The currencyService bean (which just happens to be a proxy to the EJB) is simply injected
into the currencyService property of someService.
Notice that by using a proxy factory bean to access the currencyService EJB, you do not have
to write your own service locator or business delegate code. In fact, you do not have to write
any JNDI code, nor deal with the EJB’s home interface. Furthermore, as seen in the above
example, by hiding it all behind the currencyService business interface, the SomeService is
not even aware that it is dealing with a POJO. This means that you are free to swap out the
EJB implementation of currencyService with any other implementation!
• SimpleRemoteStatelessSessionProxyFactoryBean is used
<bean id="currencyService2"
class="org.springframework.ejb.access.SimpleRemoteStatelessSessionPr
oxyFactoryBean">
<property name="jndiName" value="CurrencyConverterRemote" />
<property name="resourceRef" value="true" />
<property name="businessInterface"
value="com.CurrencyConversion.CurrencyService" />
</bean>
However, Spring provides four abstract classes to make developing EJB’s easier:
Example
public interface MyComponent {
public void myMethod(...);
...
}
Consider an example Stateless Session bean which actually delegates the implementation to
a plain java service object. We have the business interface:
public interface MyComponent {
public void myMethod(...);
...
}
Example
public class MyComponentEJB extends
AbstractStatelessSessionBean implements MyComponent {
MyComponent _myComp;
protected void onEjbCreate() throws CreateException {
_myComp = (MyComponent)
getBeanFactory().getBean(“MyComponent”);
}
public String myMethod(...) {
return _myComp.myMethod(...);
} ……
When the MyComponentEJB is created, its onEjbCreate() method retrieves the MyComponent
bean from the Spring bean factory. Then when any of its methods are invoked, they delegate
responsibility to the bean MyComponent bean.
Where does the bean facotory come fro? In typical J2EE fashion, the abstract EJB classes
retrieve the bean factory from JNDI. By default, they will look up the bean factory using
java:comp/env/ejb/BeanFactoryPath as the JNDI name. To look up the bean factory by
another JNDI name, set the beanFactoryLocatorKey property before the bean factory is
loaded.
For eg:
Example (cntd):
When using EJBs in your Spring-based applications, you have a lot of options for simplifying
how you access them. When using stateful session beans, you can use Spring's JNDI support to
simplify the EJB home interface lookup. For stateless session beans, you can go a few steps
further and create a proxy to the EJB; this allows you to treat it as a POJO bean and frees
you and your application from EJB-specific details.
In this article, we looked at Spring's support for EJB, specifically focusing on support for
stateless and stateful session beans. Using Spring's base classes, you can easily create EJBs
that are simply wrappers around dynamically loaded business logic. Using this approach
makes for easier testing and looser coupling in your application. When accessing stateless
session beans, Spring provides proxy support, freeing you of the coding burden of accessing
EJB resources and decreasing the coupling in your application.
Managing Transactions
Managing transactions
Transactions play an important role in software, ensuring that data and resources are never
left in an inconsistent state. Without them, there is a potential for data to be corrupted or
inconsistent with the business rules of the application.
Spring’s support for programmatic transaction management differs greatly from that of EJB.
EJB is coupled with a Java Transaction API (JTA) implementation. On the other hand, Spring
employs a callback mechanism that abstracts away the actual transaction implementation
from the transactional code. In fact, Spring’s transaction management support does not even
require a JTA implementation. If your application uses only a single persistent resource,
Spring can use the transactional support afforded by the persistence mechanism. This
includes JDBC, Hibernate, JDO and Apache’s OJB( object relational bridge). However, if your
application has transaction requirements that span multiple resources, Spring can support
distributed (XA) transactions using a third party JTA implementation. We will discuss Spring’s
support for programmatic transactions later on .
To use a transaction manager, you will need to declare it in your application context. Let us
see how to declare two of these transaction managers : JDBC and Hibernate.
JDBC transactions
<bean id="txManager"
class="org.springframework.jdbc.datasource.DataSourceTransactio
nManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
JDBC transactions:
If you are using straight JDBC for your applications persistence,
DataSourceTransactionManager will handle transactional boundaries for you. To use
DataSourceTransactionManager, wire it into your application’s context definition as:
<bean id="txManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
Hibernate transactions
Hibernate transactions:
If your application’s persistence is handled by Hibernate, use the
HibernateTransactionManager , by declaring it in xml as :
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:
return null;
}
});
You start by implementing the TransactionCallback interface. Since it has only one method, its often easier
to implement it as an anonymous inner-class as shown in abiove example. The code that needs to run as a
transactional unit is placed in doInTransaction() method. Calling the execute() method on the
TransactionTemplate instance will execute the coed contained within the TransactionCallback instance.
Code within the callback can roll the transaction back by calling the setRollbackOnly() method on the
TransactionStatus object. If the doInTransaction() method returns successfully, the transaction is
committed.
The TransactionTemplate instance comes from the configuration file. For example the following code
snippet injects the TransactionTemplate instance into the CurrencyServiceImpl as follows:
Notice that the transactionTemplate bean has a transactionManager property. Under the hood,
TransactionTemplate uses an implementation of PlatformTransactionManager to handle the platform-
specific details of transaction management. Here we have wired in a reference to a bean named
transactionManager, which could be any of the implementations of the PlatformTransactionManager
interface.
Programmatic transactions are good when you want complete control over transactional boundaries, but
they are a bit intrusive. Usually your transactional needs do not require such precise control over
transactional boundaries. That is why you can choose to declare your transactions outside your application
code.
Declaring transactions:
Until some time ago, declarative transaction management was available only in EJB
containers. But now Spring offers support for declarative transaction to POJO’s. This means
that your application will no longer require complex and heavyweight EJB’s just to achieve
atomic operations declaratively.
<bean id="orderProcessingDAO"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager">
<ref local="transactionManager"/></property>
<property name="target">
<ref local="orderProcessingDAOObject"/></property>
<property name="transactionAttributes">
<props>
<prop key="updateProduct">PROPAGATION_REQUIRED</prop>
<prop key="insertOrder">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
Notice that this bean has an id of orderProcessingDAO. This is so that when the application
asks for a orderProcessingDAO from the application context, it will retrieve an instance that
is wrapped by this TransactionProxyFactoryBean. The target object is normally a POJO bean
definition. The original orderProcessingDAO should be renamed so that there is no conflict in
bean id’s. Any name will work:
The TransactionProxyFactoryBean has two collaborators in addition to its target bean. The
transactionManager property indicates an instance of PlatformTransactionManager to use
when realizing the transactional context. This can be any of the
PlatformTransactionManagers discussed previously in this session.
Most Spring users choose declarative transaction management. It is the option with the
least impact on application code, and hence is most consistent with the ideals of a non-
invasive lightweight container.
Let us see how can we use these parameters to declare a transaction policy. But before this,
let us look at how each of these parameters impact how a transaction is applied.
Propagation behavior:
This defines the boundaries of the transaction with respect to the client and to the method
being called. Spring defines seven distinct propagation behavior:
1. PROPAGATION_NEVER : Indicates that the current method must not run within a
transaction. If there is an existing transaction in progress, exception is thrown
2. PROPAGATION_NOT_SUPPORTED : Indicates that the method must not run within a
transaction. If there is an existing transaction in progress, it will be suspended for the
duration of the method.
3. PROPAGATION_REQUIRED : Indicates that the method must run within a transaction. If
there is an existing transaction in progress, method will run within the transaction, else a
new transaction is started.
4. PROPAGATION_REQUIRES_NEW : Indicates that the current method must run within its
own transaction. A new transaction is started and if an existing transaction is in progress,
it will be suspended for the duration of method execution.
5. PROPAGATION_SUPPORTS : Indicates that current method does not require a
transactional context, but may run within a transaction if one is already in progress.
Isolation levels
Isolation levels:
In a typical application, multiple transactions run concurrently, often working with the same
data to get their job done. Concurrency can lead to following problems:
1.Dirty read: Occur when one transaction reads data that has been written but not yet
committed by another transaction. If the changes are later rolled back, data obtained from
first transaction will be invalid.
2.No repeatable read : Happen when a transaction perform the same query two or more
times and each time the data is different. This is usually due to another concurrent
transaction updating the data between the queries.
3.Phantom read : Are similar to No repeatable reads. These occur when a transaction (T1)
reads several rows, then a concurrent transaction (T2) inserts rows. Upon subsequent
queries, the first transaction (T1) finds additional rows that were not there before.
In a ideal situation, transactions would be completely isolated from each other, preventing
these problems. However, perfect isolation can affect performance because it often involves
locking rows in the datastore. Aggressive locking can hinder concurrency, requiring
transactions to wait on each other to do their work.
Thus it is required that we be flexible with transaction isolation. There are several levels of
isolation:
Read-only:
If a transaction only performs read operations against the underlying datastore, the
datastore may be able to apply certain optimizations that take advantage of the read-only
nature of the transaction. By declaring a transaction as read-only, you give the underlying
datastore the opportunity to apply those optimizations as it sees fit.
Transaction timeout:
If your transaction is unexpectedly long running, it may tie up underlying database resources
unnecessarily. Instead of waiting it out, you can declare a transaction to automatically roll
back after a certain number of seconds.
Transaction policy
public TransactionAttribute
<bean id=“transactionAttributeSource “
class=“org.springframework.transaction.interceptor.MatchAlwaysTransactionAttributeSource
”>
…
</bean>
With the transactionAttributeSource bean declared, all the methods proxied by the target
class of TransactionProxyFactoryBean are now performed within a transactional context. Do
notice that there is no need to specify which methods are to be transactional or even which
transactional policy to apply. That’s because we have used the
MatchAlwaysTransactionAttributeSource.
<bean id=“myTransactionAttribute"
class="org.springframework.transaction.interceptor.DefaultTransactionAttribute">
<property name=“propogationBehaviorName">
<value> PROPOGATION_REQUIRES_NEW </value>
</property>
<property name=“isolationLevelName">
<value> ISOLATION_REPEATABLE_READ </value>
</property>
</bean>
Be aware however, that while you may change the parameters of the transaction attribute
applied by MatchAlwaysTransactionAttributeSource, it will always return the same
transaction attribute, regardless of the method being transacted.
Uisng MatchAlwaysTransactionAttributeSource is great when you have a realtively simple
application and its okay to apply the same transaction policies to all methods. But in
complex applications, you will likely need to apply different transaction policies to different
methods. In which case you will need more fine grained control over which policies are
applied. So, lets take a look at another TransactionAttributeSource that allows you to
declare transactional policies on a method-to-method basis.
One of the key features of EJB specification has been CMT (container managed transactions).
Using CMT, it is possible to declare transaction policies in EJB’s deployment descriptor. Spring
took a page from EJB’s declarative transaction model, providing several transaction attribute
sources that let you declare transaction policies on POJO’s. Let us look at
NameMatchTransactionAttributeSource, a transaction attribute source that lets you declare
transactions on POJO’s.
<bean id=“transactionAttributeSource “
class=“…NameMatchTransactionAttributeSource ">
<property name=“properties ">
<props>
<prop key=“enrollStudentInCourse” >
PROPOGATION_REQUIRES_NEW, ISOLATION_REPEATABLE_READ,
-CourseException
….
Copyright © 2006 by Patni
Finally transactions can be declared to roll back or not roll back based on exceptions that are
thrown during the course of the transaction. By default, transactions are rolled back only on
runtime exceptions and not on checked exceptions. However, you can specify that a transaction
can be rolled back on specific checked exceptions as well.
For example, to have the transaction always rollback when a CourseException or its subclass is
thrown, alter the transaction attribute to appear as shown in above slide.
Notice that the CourseException is marked with negative (-) sign. Negative exception trigger a
rollback if the exception is thrown. Positive exceptions, on the other hand, indicate that the
transaction should be committed even if the exception is thrown.
Acegi Security is a powerful, flexible security solution for enterprise software, with a
particular emphasis on applications that use Spring. Using Acegi Security provides your
applications with comprehensive authentication, authorization, instance-based access
control, channel security and human user detection capabilities.
Acegi is a security framework that provides declarative security for Spring based
applications. It provides a collection of beans that are configured within a Spring application
context, taking full advantage of Spring’s support for dependency injection and AOP.
When securing web applications, Acegi uses servlet filters that intercept servlet requests to
perform authentication and enforce security. Acegi can also enforce security at a lower level
by securing method invocations. Using Spring AOP, Acegi proxies objects, applying aspects
that ensure a user has the proper authority to call the secured methods.
Regardless of whether you are securing a web application or require method-level security,
Acegi applies security using four main components as shown in above figure. Before we get
into the nitty-gritty of Acegi security, let us take a high level view of the roles that each of
these components play.
Security Interceptors: These can be thought of as a latch that prevents a user from
accessing a secured resource in your application.
Access decision manager: Performs authorization using the authentication information and
security attributes that have been associated with the secured resource. For example,
security rules may dictate that only supervisors should be allowed access to a secured
resource.
Run-as managers: A run-as manager can be used to replace your authentication with an
authentication that allows you access to the secured objects that are deeper in your
application. For eg, after being authenticated and authorized, you may have rights to view a
web page, but the objects that are used to create the page may have different security
requirements than the web page. The usefulness of run-as managers is limited in most
applications and would therefore not be pursued further in this material.
Servlet-based implementation of
Acegi
<%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %>
<%@ page import="net.sf.acegisecurity.ui.AbstractProcessingFilter,
net.sf.acegisecurity.ui.webapp.HttpSessionIntegrationFilter" %>
<%@ page import="net.sf.acegisecurity.AuthenticationException" %>
<br>Enter username:
<input type="text" name="j_username">
<br>Enter password:
<input type="text" name="j_password">
<br>
<input type="submit" value="Login">
</form>
This implementation will use forms-based authentication to verify users. Lets create a login
form that users will be redirected to whenever they attempt to access any of the restricted
site pages (example 20.1 – acelogin.jsp).
Managing Authentication
Next we need to configure the Acegi security beans in your Spring configuration , but first let
us see how Acegi manages authentication.
Managing Authentication: The AuthenticationManager interface establishes a users identity
with the single authenticate() method. However, Acegi also gives us a ProviderManager
(which implements AuthenticationManager), which in turn delegates responsibility for
authentication to one or more authentication providers. ProviderManager is given its list of
authentication providers through its providers property. A authentication provider is defined
by the AuthenticationProvider interface. Spring comes with several authentication providers
which authenticate against using container adapters, retrieves user information from a
database, retrieves user information from a JAAS login configuration, authenticates against a
remote service etc. You may think of AuthenticationProvider as a subordinate of
AuthenticationManager. Below are two of the most commonly used authentication
providers:
InMemoryDaoImpl
<bean id="inMemoryDaoImpl"
class="net.sf.acegisecurity.providers.dao.memory.InMemoryDaoImpl">
<property name="userMap">
<value>
harry=springfw,ROLE_USER,ROLE_ADMIN
barry=ineedsleep,ROLE_USER
</value>
</property>
</bean>
InMemoryDaoImpl:
Although Acegi provides several ways to authenticate user credentials (vis LDAP, a database
(as seen above), external provider etc), the easiest way is through a special provider called
InMemoryDaoImpl. This allows to configure user credentials in your configuration file. Lets
configure the Acegi security beans in your Spring configuration (Example 20.2 : login-
servlet.xml) as follows:
<bean id="inMemoryDaoImpl"
class="net.sf.acegisecurity.providers.dao.memory.InMemoryDaoImpl">
<property name="userMap">
<value>
harry=springfw,ROLE_USER,ROLE_ADMIN
barry=ineedsleep,ROLE_USER
</value>
</property>
</bean>
The userMap property takes a net.sf.acegisecurity.providers.dao.memory.UserMap object
that defines a set of usernames, passwords and privileges. However, you need not concern
yourself with constructing a UserMap instance when wiring inMemoryDaoImpl because there
is a property editor that handles the conversion of a String to a UserMap object for you.
Authentication configuration:
<bean id="daoAuthenticationProvider"
class="net.sf.acegisecurity.providers.dao.DaoAuthenticationProvider">
<property name="authenticationDao">
<ref local="inMemoryDaoImpl" />
</property>
</bean>
<bean id="authenticationManager"
class="net.sf.acegisecurity.providers.ProviderManager">
<property name="providers">
<list> <ref local="daoAuthenticationProvider" /></list>
</property>
</bean>
Next you need to tell Acegi how to determine if a user is authorized to make a specific call
(example 20.2) and in slide above.
Controlling access: Authentication is only the first step in Acegi security. After
authenticating user, Acegi must decide whether to grant access to the resources that it
secures. The AccessDecisionManager is responsible for deciding if the user has proper
privileges to access secured resources. Acegi comes with implementations of
AccessDecisionManager that are suitable for most circumstances:
Although Acegi’s decision managers are ultimately responsible fr determining the access
rights for an authenticated user, they do not arrive at their decision on their own. Instead
they poll one or more objects that vote on whether a user is granted access to a secured
resource. Once all votes are in, the decision manager tallies the votes and arrives at a final
decision.
The RoleVoter requires that the roles be configured using some role beginning with ROLE_,
like our ROLE_USER and ROLE_ADMIN.
Security Interceptors
<bean id="filterInvocationInterceptor"
class="net.sf.acegisecurity.intercept.web.FilterSecurityInterceptor">
<property name="authenticationManager">
<ref local="authenticationManager" /></property>
<property name="accessDecisionManager">
<ref local="httpRequestAccessDecisionManager" /></property>
<property name="objectDefinitionSource">
<value>
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
\A/admin/.*\Z=ROLE_ADMIN
\A/user/.*\Z=ROLE_USER,ROLE_ADMIN
</value></property>
</bean>
You now need to configure a FilterSecurityInterceptor that protects access to resources. You
configure it to point to your ProviderManager and DecisionManager , then feed it a list of
protected resources (example 20.2 and code snippet in above slide).
Note the CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON directive. There are other
directives like PATTERN_TYPE_APACHE_ANT , for Ant-style pattern matching. The above list
can be read as follows: Any URL anywhere in the application that ends with any extension
requires user to belong to ROLE_USER.For example :
\A/.*/*.htm\Z=ROLE_USER allows users with ROLE_USER privileges to acees all files with
extension as .htm.
Servlet filters
<bean id="securityEnforcementFilter"
class="net.sf.acegisecurity.intercept.web.SecurityEnforcementFilter">
<property name="filterSecurityInterceptor">
<ref local="filterInvocationInterceptor" /></property>
<property name="authenticationEntryPoint">
<ref local="authenticationProcessingFilterEntryPoint" /><property>
</bean>
<bean id="authenticationProcessingFilterEntryPoint"
class="net.sf.acegisecurity.ui.webapp.AuthenticationProcessingFilterEntry
Point">
<property name="loginFormUrl">
<value>/acelogin.jsp</value> </property>
<property name="forceHttps">
<value>false</value></property>
</bean>
Servlet filters
<bean id="authenticationProcessingFilter"
class="net.sf.acegisecurity.ui.webapp.AuthenticationProcessingFilter">
<property name="authenticationManager">
<ref local="authenticationManager" />
</property>
<property name="authenticationFailureUrl">
<value>/acelogin.jsp?login_error=1</value>
</property>
<property name="defaultTargetUrl">
<value>/</value>
</property>
<property name="filterProcessesUrl">
<value>/j_acegi_security_check</value>
</property>
</bean>
The web.xml
<filter>
<filter-name>acegi authentication processing filter</filter-name>
<filter-class>net.sf.acegisecurity.util.FilterToBeanProxy
</filter-class>
<init-param>
<param-name>targetClass
</param-name>
<param-value>
net.sf.acegisecurity.ui.webapp.AuthenticationProcessingFilter
</param-value>
</init-param>
</filter
• web.xml
Copyright © 2006 by Patni
If FooFilter needs a reference to a Bar bean to do its job? How can you inject an instance of
Bar into FooFilter? Through the FilterToBeanProxy bean. This is a special servlet filter that
delegates its work to a bean in the Spring application context. The delegate bean
implements the javax.servlet.Filter interface but is configured in the Spring Configuration
file instead of web.xml.
By using FilterToBeanProxy, you are able to configure the actual filter in Spring, taking full
advantage of Spring’s support for dependency injection. The web.xml (example
20.3)contains only the <filter> declaration for FilterToBeanProxy (see slide above). The
actual filter is configured in Spring Configuration file.
The targetClass initialization parameter is set to the fully qualified class name of the
delegate filter bean.
<bean id=“autoProxyCreator”
class=“org.springframework.aop.framework.autoproxy.
BeanNameAutoProxyCreator”>
<property name=“interceptorNames”>
<list><value>securityInterceptor</value></list>
</property>
<property name=“beanNames”>
<list><value> ExchangeService </value>
<value>CurrencyConverter</value>
</list>
</property>
</bean>
We will now see how to secure a method on a bean instead of a servlet. EJB security works
by assigning users roles, giving permissions to those roles and then assigning permissions to
individual methods. In Spring, to use that model, you will want to secure a method on a bean
in the context, instead. In most cases, you will want to secure methods in the façade layer
that controls your data model.
Acegi takes advantage of Spring’s AOP support to provide declarative method-level security.
That means that instead of setting up a SecurityEnforcementFilter to enforce security, you
will set up a Spring AOP proxy that intercepts method invocations and passes control to a
security interceptor.
Method based security relies on user roles, just like servlet-based security does. To establish
access rules for methods on a bean, you have to create an instance of Acegi’s
MethodSecurityInterceptor.
MethodSecurityInterceptor does for method invocations what filterSecurityInterceptor does
for servlet requests. That is, it intercepts the invocation and coordinates the efforts of the
authentication manager and the Decision Manager to ensure that method requirements are
met.
Similarly, it will have a property called objectDefinitionSource that lists the methods on the
beans that need to be secured and what roles have access to them. For example, all
members of ROLE_USER should be able to read data from the database, but only members of
ROLE_ADMIN should be able to save, update or delete.
The method pattern includes the fully qualified class name and the method name of the
method(s) to be secured. You may also use wildcards at either the beginning or end of a
method pattern to match multiple methods. Eg :
Training.spring.CourseService.enroll*=ROLE_ADMIN,ROLE_REGISTRAR
When a secured method is called, MethodSecurityInterceptor will determine if the user has
been authenticated and has been granted the appropriate authorities to call the method. If
so, the call will proceed to the target method. If not, a AcegiSecurityException will be
thrown. More specifically, a AuthenticationException will be thrown if user cannot be
authenticated. Or if the user has not been granted authority to make the call, an
AccessDeniedException will be thrown. In keeping with Spring’s exception philosophy,
AcegiSecurityException is an unchecked exception. The calling code can either catch or
ignore the exception.
Summary:
Also, notice that much of the configuration required to secure an application with Acegi
is ignorant of the application that it is securing. The only Acegi component that really
needs to know any specifics about the secured application is the object definition source
where you associate a secured resource with the authorities required to access the
resource.
• Infrastructure exceptions are not usually recoverable. While it’s possible to catch unchecked
exceptions when one is recoverable, there is no benefit in being forced to catch or throw
exceptions in the vast majority of cases where no recovery is possible.
• Try/catch blocks that don’t add value are verbose and obfuscate code. It is not lazy to want to
avoid pointless code; it obfuscates intention and will pose higher maintenance costs forever.
Avoiding overuse of checked exceptions is consistent with the overall Spring goal of reducing the
amount of code that doesn’t do anything in typical applications.
Using checked exceptions for infrastructural failures sounds good in theory, but practice shows
differently. For example, if you analyze real applications using JDBC or entity beans (both of which
APIs use checked exceptions heavily), you will find a majority of catch blocks that merely wrap the
exception (often losing the stack trace), rather than adding any value. Thus not only the catch
block is often redundant, there are also often many redundant exception classes.
To confirm Spring’s choice of unchecked infrastructure exceptions, compare the practice of
leading persistence frameworks: JDO and TopLink have always used unchecked exceptions;
Hibernate 3 will switch from checked to unchecked exceptions. Of course it’s essential that a
framework throwing unchecked exceptions must document those exceptions.
Spring’s well-defined, well-documented hierarchies are invaluable here; for example, any code
using Spring data access functionality may throw DataAccessException, but no unexpected
unchecked exceptions (unless there is a lower-level problem such as OutOfMemoryError, which
could still occur if Spring itself used checked exceptions).
With success, there is always some criticism. The most compelling against Spring is that it is not
standard, meaning that it is not part of J2EE specification and it has not been developed through
Java Community process. The same folks who argue against Spring advocate EJB’s, which are a
standard. But the main reason for standards is to ensure portability across app servers. Code
developed for one server must run on another, but porting EJB’s from one EJB container to
another is not as simple as it should be. Different vendors require different deployment
descriptors and there is no common way of configuring data sources or other container
dependencies. In contrast, coding business logic with spring is highly portable across containers –
with no changes to code or deployment descriptors.
While spring “makes things easier”, some developers complain that its too heavyweight. However,
spring is really a la carte framework, where you can pick and choose what you want to use.
To Summarize
Summary:
Spring is a powerful framework that solves many common problems in J2EE. Many Spring features
are also usable in a wide range of Java environments, beyond classic J2EE.
Spring provides a consistent way of managing business objects and encourages good practices such
as programming to interfaces, rather than classes. The architectural basis of Spring is an Inversion
of Control container based around the use of JavaBean properties. However, this is only part of
the overall picture: Spring is unique in that it uses its IoC container as the basic building block in a
comprehensive solution that addresses all architectural tiers.
Spring provides a unique data access abstraction, including a simple and productive JDBC
framework that greatly improves productivity and reduces the likelihood of errors. Spring's data
access architecture also integrates with TopLink, Hibernate, JDO and other O/R mapping
solutions.
Spring also provides a unique transaction management abstraction, which enables a consistent
programming model over a variety of underlying transaction technologies, such as JTA or JDBC.
Spring provides an AOP framework written in standard Java, which provides declarative
transaction management and other enterprise services to be applied to POJOs or - if you wish -
the ability to implement your own custom aspects. This framework is powerful enough to enable
many applications to dispense with the complexity of EJB, while enjoying key services
traditionally associated with EJB.
Spring also provides a powerful and flexible MVC web framework that is integrated into the
overall IoC container.
Bibliography
Web resources
• http://www.theserverside.com/tt/articles/article.tss?l=
SpringFramework – article by Rod Johnson
• http://www.springframework.org
• http://forum.springframework.org
• http://java.about.com/od/springframework/ - for
downloads, articles etc.
• http://www.springframework.org/docs/reference/index
.html – for reference
Thank you.