What Does Spring Do
What Does Spring Do
Spring provides a lot of functionality, so I'll quickly review each major area in turn.
Mission statement
Firstly, let's be clear on Spring's scope. Although Spring covers a lot of ground, we
have a clear vision as to what it should and shouldn't address.
Spring does not reinvent the wheel. Thus you'll find no logging packages in Spring,
no connection pools, no distributed transaction coordinator. All these things are
provided by open source projects (such as Commons Logging, which we use for all
our log output, or Commons DBCP), or by your application server. For the same
reason, we don't provide an O/R mapping layer. There are good solutions to this
problem such as TopLink, Hibernate and JDO.
Spring does aim to make existing technologies easier to use. For example, although
we are not in the business of low-level transaction coordination, we do provide an
abstraction layer over JTA or any other transaction strategy.
Spring doesn't directly compete with other open source projects unless we feel we
can provide something new. For example, like many developers, we have never been
happy with Struts, and felt that there was room for improvement in MVC web
frameworks. (With Spring MVC adoption growing rapidly, it seems that many agree
with us.) In some areas, such as its lightweight IoC container and AOP framework,
Spring does have direct competition, but Spring was a pioneer in those areas.
Spring benefits from internal consistency. All the developers are singing from the
same hymn sheet, the fundamental ideas remaining faithful to those of Expert One-
on-One J2EE Design and Development. And we've been able to use some central
concepts, such as Inversion of Control, across multiple areas.
1
The next higher layer of abstraction is the bean factory. A Spring bean factory is a
generic factory that enables objects to be retrieved by name, and which can manage
relationships between objects.
• Singleton: in this case, there's one shared instance of the object with a
particular name, which will be retrieved on lookup. This is the default, and
most often used, mode. It's ideal for stateless service objects.
• Prototype or non-singleton: in this case, each retrieval will result in the
creation of an independent object. For example, this could be used to allow
each caller to have its own distinct object reference.
Because the Spring container manages relationships between objects, it can add
value where necessary through services such as transparent pooling for managed
POJOs, and support for hot swapping, where the containerintroduces a level of
indirection that allows the target of a reference to be swapped at runtime without
affecting callers and without loss of thread safety. One of the beauties
of Dependency Injection (discussed shortly) is that all this is possible transparently,
with no API involved.
Each bean definition can be a POJO (defined by class name and JavaBean
initialisation properties or constructorarguments), or a FactoryBean.
The FactoryBean interface adds a level of indirection. Typically this is used to create
proxied objects using AOP or other approaches: for example, proxies that add
declarative transaction management. This is conceptually similar to EJB interception,
but works out much simpler in practice, and is more powerful.
This motivation for the use of JavaBeans is described in Chapter 4 of Expert One-on-
One J2EE Design and Development, which is available on the ServerSide as a free
PDF (/articles/article.tss?l=RodJohnsonInterview).
2
Through its bean factory concept, Spring is an Inversion of Control container. (I
don't much like the term container, as it conjures up visions of
heavyweight containers such as EJB containers. A Spring BeanFactory is a container
that can be created in a single line of code, and requires no special deployment
steps.) Spring is most closely identified with a flavor of Inversion of Control known
as Dependency Injection--a name coined by Martin Fowler, Rod Johnson and the
PicoContainer team in late 2003.
The two major flavors of Dependency Injection are Setter Injection (injection via
JavaBean setters); andConstructor Injection (injection via
constructor arguments). Spring provides sophisticated support for both, and even
allows you to mix the two when configuring the one object.
As well as supporting all forms of Dependency Injection, Spring also provides a range
of callback events, and an API for traditional lookup where necessary. However, we
recommend a pure Dependency Injection approach in general.
3
errors when the framework configures the application; you don't have to
worry about class cast exceptions in your code.
• Dependencies are explicit. For example, if an application class tries to load a
properties file or connect to a database on instantiation, the environmental
assumptions may not be obvious without reading the code (complicating
testing and reducing deployment flexibility). With a Dependency Injection
approach, dependencies are explicit, and evident in constructor or JavaBean
properties.
• Most business objects don't depend on IoC container APIs. This makes it easy
to use legacy code, and easy to use objects either inside or outside the IoC
container. For example, Spring users often configure the Jakarta Commons
DBCP DataSource as a Spring bean: there's no need to write any custom code
to do this. We say that an IoC container isn't invasive: using it won't invade
your code with dependency on its APIs. Almost any POJO can become a
component in a Spring bean factory. Existing JavaBeans or objects with multi-
argument constructors work particularly well, but Spring also provides unique
support for instantiating objects from static factory methods or even methods
on other objects managed by the IoC container.
In my experience and that of Spring users, it's hard to overemphasize the benefits
that IoC--and, especially, Dependency Injection--brings to application code.
Dependency Injection is not a new concept, although it's only recently made prime
time in the J2EE community. There are alternative DI containers: notably,
PicoContainer and HiveMind. PicoContainer is particularly lightweight and emphasizes
the expression of dependencies through constructors rather than JavaBean
properties. It does not use metadata outside Java code, which limits its functionality
in comparison with Spring. HiveMind is conceptually more similar to Spring (also
aiming at more than just IoC), although it lacks the comprehensive scope of the
Spring project or the same scale of user community. EJB 3.0 will provide a basic DI
capability as well.
Spring BeanFactories are very lightweight. Users have successfully used them inside
applets, as well as standalone Swing applications. (They also work fine within an EJB
container.) There are no special deployment steps and no detectable startup time
associated with the container itself (although certain objects configured by the
container may of course take time to initialize). This ability to instantiate a container
almost instantly in any tier of an application can be very valuable.
The Spring BeanFactory concept is used throughout Spring, and is a key reason that
Spring is so internally consistent. Spring is also unique among IoC containers in that
it uses IoC as a basic concept throughout a full-featured framework.
4
layer can be interrelated, and their relationships managed by the owning factory.
Having a well-defined layer of business objects is very important to a successful
architecture.
XmlBeanFactory example
Spring users normally configure their applications in XML "bean definition" files. The
root of a Spring XML bean definition document is a <beans> element.
The <beans> element contains one or more <bean> definitions. We normally specify
the class and properties of each bean definition. We must also specify the id, which
will be the name that we'll use this bean with in our code.
Let's look at a simple example, which configures three application objects with
relationships commonly seen in J2EE applications:
• A J2EE DataSource
• A DAO that uses the DataSource
• A business object that uses the DAO in the course of its work
<beans>
<bean id="myDataSource"
class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/mydb" />
<property name="username" value="someone" />
</bean>
5
PropertyEditor mechanism to convert String representations to other types if
necessary.
Now we define the DAO, which has a bean reference to the DataSource.
Relationships between beans are specified using the "ref" attribute
or <ref> element:
<bean id="exampleDataAccessObject"
class="example.ExampleDataAccessObject">
<property name="dataSource" ref="myDataSource" />
</bean>
The business object has a reference to the DAO, and an int property
(exampleParam). In this case, I've used the subelement syntax familiar to those
who've used Spring prior to 1.2:
<bean id="exampleBusinessObject"
class="example.ExampleBusinessObject">
<property name="dataAccessObject"><ref
bean="exampleDataAccessObject"/></property>
<property name="exampleParam"><value>10</value></property>
</bean>
</beans>
We could use the autowire feature as follows in the above example, if we didn't want
to code these relationships explicitly:
<bean id="exampleBusinessObject"
class="example.ExampleBusinessObject"
autowire="byType">
With this usage, Spring will work out that the dataSource property of
exampleBusinessObject should be set to the implementation of DataSource it finds in
the present BeanFactory. It's an error if there is none, or more than one, bean of the
required type in the present BeanFactory. We still need to set the exampleParam
property, as it's not a reference.
Autowire support has the advantage of reducing the volume of configuration. It also
means that the container can learn about application structure using reflection, so if
you add an additional constructor argument of JavaBean property, it may be
6
successfully populated without any need to change configuration. The tradeoffs
around autowiring need to be evaluated carefully.
Externalizing relationships from Java code has an enormous benefit over hard coding
it, as it's possible to change the XML file without changing a line of Java code. For
example, we could simply change the myDataSource bean definition to refer to a
different bean class to use an alternative connection pool, or a test data source. We
could use Spring's JNDI location FactoryBean to get a datasource from an application
server in a single alternative XML stanza, as follows. There would be no impact on
Java code or any other bean definitions.
<bean id="myDataSource"
class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="jdbc/myDataSource" />
</bean>
Now let's look at the Java code for the example business object. Note that there are
no Spring dependencies in the code listing below. Unlike an EJB container, a Spring
BeanFactory is not invasive: you don't normally need to code awareness of it into
application objects.
Note the property setters, which correspond to the XML references in the bean
definition document. These are invoked by Spring before the object is used.
Such application beans do not need to depend on Spring: They don't need to
implement any Spring interfaces or extend Spring classes: they just need to observe
JavaBeans naming convention. Reusing one outside of a Spring application context is
easy, for example in a test environment. Just instantiate it with its default
constructor, and set its properties manually,
via setDataSource() and setExampleParam() calls. So long as you have a no-args
constructor, you're free to define other constructors taking multiple properties if you
want to support programmatic construction in a single line of code.
Note that the JavaBean properties are not declared on the business interface callers
will work with. They're an implementation detail. We can easily "plug in" different
7
implementing classes that have different bean properties without affecting connected
objects or calling code.
Of course Spring XML bean factories have many more capabilities than described
here, but this should give you a feel for the basic approach. As well as simple
properties, and properties for which you have a JavaBeans PropertyEditor, Spring
can handle lists, maps and java.util.Properties. Other advanced container
capabilities include:
Bean factories and application contexts are often associated with a scope defined by
the J2EE server or web container, such as:
These hooks provided by the J2EE specification generally avoid the need to use a
Singleton to bootstrap a bean factory.
This code will work outside an application server: it doesn't even depend on J2EE, as
the Spring IoC container is pure Java. The Spring Rich project (a framework for
simplifying the development of Swing applications using Spring) demonstrates how
8
Spring can be used outside a J2EE environment, as do Spring's integration testing
features, discussed later in this article. Dependency Injection and the related
functionality is too general and valuable to be confined to a J2EE, or server-side,
environment.
JDBC offers fairly good abstraction from the underlying database, but is a painful API
to use. Some of the problemsinclude:
• The need for verbose error handling to ensure that ResultSets, Statements
and (most importantly) Connections are closed after use. This means that
correct use of JDBC can quickly result in a lot of code. It's also a common
source of errors. Connection leaks can quickly bring applications down under
load.
• The relatively uninformative SQLException. JDBC does not offer an exception
hierarchy, but throws SQLException in response to all errors. Finding out what
actually went wrong - for example, was the problem a deadlock or invalid
SQL? - involves examining the SQLState value and error code. The meaning
of these values varies between databases.
• By providing APIs that move tedious and error-prone exception handling out
of application code into the framework. The framework takes care of all
exception handling; application code can concentrate on issuing the
appropriate SQL and extracting results.
• By providing a meaningful exception hierarchy for your application code to
work with in place of SQLException. When Spring first obtains a connection
from a DataSource it examines the metadata to determine the database
product. It uses this knowledge to map SQLExceptions to the correct
exception in its own hierarchy descended
from org.springframework.dao.DataAccessException. Thus your code can
work with meaningful exceptions, and need not worry about proprietary
SQLState or error codes. Spring's data access exceptions are not JDBC-
specific, so your DAOs are not necessarily tied to JDBC because of the
exceptions they may throw.
The following UML class diagram illustrates a part of this data access exception
hierarchy, indicating its sophistication. Note that none of the exceptions shown here
is JDBC-specific. There are JDBC-specific subclasses of some of these exceptions, but
calling code is generally abstracted wholly away from dependence on JDBC: an
essential if you wish to use truly API-agnostic DAO interfaces to hide your
persistence strategy.
9
hence error handling and connection acquisition and release - from application code
inside the framework. This is a different type of Inversion of Control, but equally
valuable to that used for configuration management.
Spring uses a similar callback approach to address several other APIs that involve
special steps to acquire and cleanup resources, such as JDO (acquiring and
relinquishing a PersistenceManager), transaction management (using JTA) and JNDI.
Spring classes that perform such callbacks are called templates.
For example, the Spring JdbcTemplate object can be used to perform a SQL
query and save the results in a list as follows:
The mapRow callback method will be invoked for each row of the ResultSet.
Note that application code within the callback is free to throw SQLException: Spring
will catch any exceptions and rethrow them in its own hierarchy. The application
developer can choose which exceptions, if any, to catch and handle.
The Spring JDBC abstraction has a very low performance overhead beyond standard
JDBC, even when working with huge result sets. (In one project in 2004, we profiled
the performance of a financial application performing up to 1.2 million inserts per
transaction. The overhead of Spring JDBC was minimal, and the use of Spring
facilitated the tuning of batch sizes and other parameters.)
10
public UserQuery(DataSource datasource) {
super(datasource, "SELECT * FROM PUB_USER_ADDRESS WHERE
USER_ID = ?");
declareParameter(new SqlParameter(Types.NUMERIC));
compile();
}
Such objects are often inner classes inside DAOs. They are threadsafe, unless the
subclass does something unusual.
Data access exceptions not usually recoverable. For example, if we can't connect to
the database, a particular business object is unlikely to be able to work around the
problem. One potential exception is optimistic lockingviolations, but not all
applications use optimistic locking. It's usually bad to be forced to write code to
catch fatal exceptions that can't be sensibly handled. Letting them propagate to top-
level handlers like the servlet or EJB container is usually more appropriate. All Spring
data access exceptions are subclasses of DataAccessException, so if we do choose
to catch all Spring data access exceptions, we can easily do so.
Note that if we do want to recover from an unchecked data access exception, we can
still do so. We can write code to handle only the recoverable condition. For example,
if we consider that only an optimistic locking violation is recoverable, we can write
code in a Spring DAO as follows:
11
try {
// do work
}
catch (OptimisticLockingFailureException ex) {
// I'm interested in this
}
If Spring data access exceptions were checked, we'd need to write the following
code. Note that we could choose to write this anyway:
try {
// do work
}
catch (OptimisticLockingFailureException ex) {
// I'm interested in this
}
catch (DataAccessException ex) {
// Fatal; just rethrow it
}
One potential objection to the first example - that the compiler can't enforce
handling the potentially recoverable exception - applies also to the second. Because
we're forced to catch the base exception (DataAccessException), the compiler won't
enforce a check for a subclass (OptimisticLockingFailureException). So
the compiler would force us to write code to handle an unrecoverable problem, but
provide no help in forcing us to deal with the recoverable problem.
Spring's use of unchecked data access exceptions is consistent with that of many -
probably most - successful persistence frameworks. (Indeed, it was partly inspired
by JDO.) JDBC is one of the few data access APIs to use checked exceptions. TopLink
and JDO, for example, use unchecked exceptions exclusively. Hibernate switched
from checked to unchecked exceptions in version 3.
In practice we find that all this amounts to substantial productivity gains and fewer
bugs. I used to loathe writing JDBC code; now I find that I can focus on the SQL I
want to execute, rather than the incidentals of JDBC resource management.
12
Spring's JDBC abstraction can be used standalone if desired - you are not forced to
use the other parts of Spring.
Of course often you want to use O/R mapping, rather than use relational data
access. Your overall application framework must support this also. Thus Spring
integrates out of the box with Hibernate (versions 2 and 3), JDO (versions 1 and 2),
TopLink and other ORM products. Its data access architecture allows it to integrate
with anyunderlying data access technology. Spring and Hibernate are a particularly
popular combination.
Why would you use an ORM product plus Spring, instead of the ORM product
directly? Spring adds significant value in the following areas:
13
make the eventual switch much easier. Spring's abstraction of your ORM
tool's Transactions and Exceptions, along with its IoC approach which allow
you to easily swap in mapper/DAO objects implementing data-access
functionality, make it easy to isolate all ORM-specific code in one area of your
application, without sacrificing any of the power of your ORM tool. The
PetClinic sample application shipped with Spring demonstrates the portability
benefits that Spring offers, through providing variants that use JDBC,
Hibernate, TopLink and Apache OJB to implement the persistence layer.
• Ease of testing. Spring's inversion of control approach makes it easy to
swap the implementations and locations of resources such as Hibernate
session factories, datasources, transaction managers, and mapper object
implementations (if needed). This makes it much easier to isolate and test
each piece of persistence-related code in isolation.
Above all, Spring facilitates a mix-and-match approach to data access. Despite the
claims of some ORM vendors, ORM is not the solution to all problems, although it is a
valuable productivity win in many cases. Spring enables a consistentarchitecture,
and transaction strategy, even if you mix and match persistence approaches, even
without using JTA.
In cases where ORM is not ideally suited, Spring's simplified JDBC is not the only
option: the "mapped statement" approach provided by iBATIS SQL Maps is worth
a look. It provides a high level of control over SQL, while still automating the
creation of mapped objects from query results. Spring integrates with SQL Maps out
of the box. Spring's PetStore sample application illustrates iBATIS
integration. Transaction management
Abstracting a data access API is not enough; we also need to consider transaction
management. JTA is the obvious solution, but it's a cumbersome API to use directly,
and as a result many J2EE developers used to feel that EJB CMT is the only rational
option for transaction management. Spring has changed that.
Spring provides its own abstraction for transaction management. Spring uses this to
deliver:
Spring's transaction abstraction is unique in that it's not tied to JTA or any other
transaction management technology. Spring uses the concept of a transaction
strategy that decouples application code from the underlying transaction
infrastructure (such as JDBC).
Why should you care about this? Isn't JTA the best answer for all transaction
management? If you're writing an application that uses only a single database, you
don't need the complexity of JTA. You're not interested in XA transactions or two
phase commit. You may not even need a high-end application server that provides
14
these things. But, on the other hand, you don't want to have to rewrite your code
should you ever have to work with multiple data sources.
Imagine you decide to avoid the overhead of JTA by using JDBC or Hibernate
transactions directly. If you ever need to work with multiple data sources, you'll have
to rip out all that transaction management code and replace it with JTA transactions.
This isn't very attractive and led most writers on J2EE, including myself, to
recommend using global JTA transactions exclusively, effectively ruling out using a
simple web container such as Tomcat for transactional applications. Using the Spring
transaction abstraction, however, you only have to reconfigure Spring to use a JTA,
rather than JDBC or Hibernate, transaction strategy and you're done. This is a
configuration change, not a code change. Thus, Spring enables you to write
applications that can scale down as well as up.
AOP
Since 2003 there has been much interest in applying AOP solutions to those
enterprise concerns, such as transaction management, which have traditionally been
addressed by EJB.
The first goal of Spring's AOP support is to provide J2EE services to POJOs. Spring
AOP is portable between application servers, so there's no risk of vendor lock in. It
works in either web or EJB container, and has been used successfully in WebLogic,
Tomcat, JBoss, Resin, Jetty, Orion and many other application servers and web
containers.
Spring AOP supports method interception. Key AOP concepts supported include:
Spring supports both stateful (one instance per advised object) and
stateless interceptors (one instance for all advice).
Spring does not support field interception. This is a deliberate design decision. I have
always felt that field interception violates encapsulation. I prefer to think of AOP
as complementing, rather than conflicting with, OOP. In five or ten years time we will
probably have travelled a lot farther on the AOP learning curve and feel comfortable
giving AOP a seat at the top table of application design. (At that point language-
based solutions such as AspectJ may be far more attractive than they are today.)
15
Spring implements AOP using dynamic proxies (where an interface exists) or CGLIB
byte code generation at runtime (which enables proxying of classes). Both these
approaches work in any application server, or in a standalone environment.
Spring was the first AOP framework to implement the AOP Alliance interfaces
(www.sourceforge.net/projects/aopalliance). These represent an attempt to
define interfaces allowing interoperability of interceptors between AOP frameworks.
Spring integrates with AspectJ, providing the ability to seamlessly include AspectJ
aspects into Spring applications . Since Spring 1.1 it has been possible to
dependency inject AspectJ aspects using the Spring IoC container, just like any Java
class. Thus AspectJ aspects can depend on any Spring-managed objects. The
integration with the forthcoming AspectJ 5 release is still more exciting, with AspectJ
set to provide the ability to dependency inject any POJO using Spring, based on an
annotation-driven pointcut.
Because Spring advises objects at instance, rather than class loader, level, it is
possible to use multiple instances of the same class with different advice, or use
unadvised instances along with advised instances.
16
doing JDBC operations on Oracle, you can use declarative nested transactions
using Spring.
• Transaction management is not tied to JTA. As explained above, Spring
transaction management can work with different transaction strategies.
Spring AOP integrates transparently with the Spring BeanFactory concept. Code
obtaining an object from a Spring BeanFactory doesn't need to know whether or not
it is advised. As with any object, the contract will be defined by the interfaces the
object implements.
<bean id="myTest"
class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces">
<value>org.springframework.beans.ITestBean</value>
</property>
<property name="interceptorNames">
<list>
<value>txInterceptor</value>
<value>target</value>
</list>
</property>
</bean>
Note that the class of the bean definition is always the AOP framework's
ProxyFactoryBean, although the type of the bean as used in references or returned
by the BeanFactory getBean() method will depend on the proxy interfaces. (Multiple
proxy methods are supported.) The "interceptorNames" property of the
ProxyFactoryBean takes a list of String. (Bean names must be used rather than bean
references, as new instances of stateful interceptors may need to be created if the
proxy is a "prototype", rather than a singleton bean definition.) The names in this list
can beinterceptors or pointcuts (interceptors and information about when they
17
should apply). The "target" value in the list above automatically creates an "invoker
interceptor" wrapping the target object. It is the name of a bean in the factory that
implements the proxy interface. The myTest bean in this example can be used like
any other bean in the bean factory. For example, other objects can reference it via
<ref> elements and these references will be set by Spring IoC.
There are a number of ways to set up proxying more concisely, if you don't need the
full power of the AOP framework, such as using Java 5.0 annotations to drive
transactional proxying without XML metadata, or the ability to use a single piece of
XML to apply a consistent proxying strategy to many beans defined in a Spring
factory.
We believe that it's generally best to externalize the wiring of applications from Java
code, and AOP is no exception.
The use of AOP as an alternative to EJB (version 2 or above) for delivering enterprise
services is growing in importance. Spring has successfully demonstrated the value
proposition.
Spring's MVC model is most similar to that of Struts, although it is not derived from
Struts. A Spring Controller is similar to a Struts Action in that it is a multithreaded
service object, with a single instance executing on behalf of all clients. However,
we believe that Spring MVC has some significant advantages over Struts. For
example:
18
• 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 than Struts web tiers, due to
the avoidance of forced concreteinheritance 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.
As in Struts 1.1 and above, you can have as many dispatcher servlets as you need in
a Spring MVC application.
The following example shows how a simple Spring Controller can access business
objects defined in the same application context. This controller performs a Google
search in its handleRequest() method:
19
return new ModelAndView("googleResults", "result",
result);
}
}
Spring also provides support for data binding, forms, wizards and more complex
workflow. A forthcoming article in this series will discuss Spring MVC in detail.
If your requirements are really complex, you should consider Spring Web Flow, a
powerful framework that provides a higher level of abstraction for web flows than
any traditional web MVC framework, and was discussed in a recent TSS article by its
architect, Keith Donald.
If you're happy with your favourite MVC framework, Spring's layered infrastructure
allows you to use the rest of Spring without our MVC layer. We have Spring users
who use Spring for middle tier management and data access but use Struts,
WebWork, Tapestry or JSF in the web tier.
Implementing EJBs
If you choose to use EJB, Spring can provide important benefits in both EJB
implementation and client-side access to EJBs.
It's now widely regarded as a best practice to refactor business logic into POJOs
behind EJB facades. (Among other things, this makes it much easier to unit test
business logic, as EJBs depend heavily on the container and are hard to test in
isolation.) Spring provides convenient superclasses for session beans and message
driven beans that make this very easy, by automatically loading a BeanFactory
based on an XML document included in the EJB Jar file.
This means that a stateless session EJB might obtain and use a collaborator like this:
import org.springframework.ejb.support.AbstractStatelessSessionBean;
20
protected void onEjbCreate() {
this.myPOJO = getBeanFactory().getBean("myPOJO");
}
We tell Spring where to load the XML document via an environment variable
definition named ejb/BeanFactoryPath in the standard ejb-jar.xml deployment
descriptor, as follows:
<session>
<ejb-name>myComponent</ejb-name>
<local-home>com.test.ejb.myEjbBeanLocalHome</local-home>
<local>com.mycom.MyComponentLocal</local>
<ejb-class>com.mycom.MyComponentEJB</ejb-class>
<session-type>Stateless</session-type>
<transaction-type>Container</transaction-type>
<env-entry>
<env-entry-name>ejb/BeanFactoryPath</env-entry-name>
<env-entry-type>java.lang.String</env-entry-type>
<env-entry-value>/myComponent-ejb-beans.xml</env-entry-
value></env-entry>
</env-entry>
</session>
The myComponent-ejb-beans.xml file will be loaded from the classpath: in this case,
in the root of the EJB Jar file. Each EJB can specify its own XML document, so this
mechanism can be used multiple times per EJB Jar file.
When EJB 3.0 is available in public draft, we will offer support for the use of the
Spring IoC container to provide richer Dependency Injection semantics in that
environment. We will also integrate the JSR-220 O/R mapping API with Spring as a
supported data access API.
Using EJBs
Spring also makes it much easier to use, as well as implement EJBs. Many EJB
applications use the Service Locatorand Business Delegate patterns. These are
better than spraying JNDI lookups throughout client code, but their usual
implementations have significant disadvantages. For example:
21
• 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.
For these and other reasons, traditional EJB access, as demonstrated in applications
such as the Sun Adventure Builder and OTN J2EE Virtual Shopping Mall, can reduce
productivity and result in significant complexity.
Spring steps beyond this by introducing codeless business delegates. With Spring
you'll never need to write another Service Locator, another JNDI lookup,
or duplicate methods in a hand-coded Business Delegate unless you're adding real
value.
For example, imagine that we have a web controller that uses a local EJB. We'll
follow best practice and use the EJBBusiness Methods Interface pattern, so that
the EJB's local interface extends a non EJB-specific business methodsinterface. (One
of the main reasons to do this is to ensure that synchronization between method
signatures in local interface and bean implementation class is automatic.) Let's call
this business methods interface MyComponent. Of course we'll also need
to implement the local home interface and provide a bean implementation class that
implements SessionBean and the MyComponent business methods interface.
With Spring EJB access, the only Java coding we'll need to do to hook up our web
tier controller to the EJB implementation is to expose a setter method of type
MyComponent on our controller. This will save the reference as an instance variable
like this:
Spring does the rest of the work automatically, via XML bean definition entries like
this. LocalStatelessSessionProxyFactoryBean is a generic factory bean that can be
used for any EJB. The object it creates can be cast by Spring to the MyComponent
type automatically.
<bean id="myComponent"
class="org.springframework.ejb.access.LocalStatelessSessionProxyFactory
Bean">
22
/>
</bean>
<bean id="myController"
class = "com.mycom.myController"
>
<property name="myComponent" ref="myComponent" />
</bean>
There's a lot of magic happening behind the scenes, courtesy of the Spring AOP
framework, although you aren't forced to work with AOP concepts to enjoy the
results. The "myComponent" bean definition creates a proxy for the EJB, which
implements the business method interface. The EJB local home is cached on startup,
so there's normally only a single JNDI lookup. (There is also support for retry on
failure, so an EJB redeployment won't cause the client to fail.) Eachtime the EJB is
invoked, the proxy invokes the create() method on the local EJB and invokes the
corresponding business method on the EJB.
The myController bean definition sets the myController property of the controller
class to this proxy.
• The web tier code has no dependence on the use of EJB. If we want to replace
this EJB reference with a POJO or a mock object or other test stub, we could
simply change the myComponent bean definition without changing a line of
Java code
• We haven't had to write a single line of JNDI lookup or other EJB plumbing
code as part of our application.
We can also apply the same approach to remote EJBs, via the similar
org.springframework.ejb.access.SimpleRemoteStatelessSessionProxyFactoryBean
factory bean. However, it's trickier to conceal the RemoteExceptions on the business
methods interface of a remote EJB. (Spring does let you do this, if you wish to
provide a client-side service interface that matches the EJB remote interface but
without the "throws RemoteException" clause in the method signatures.)
Testing
As you've probably gathered, I and the other Spring developers are firm believers in
the importance of comprehensiveunit testing. We believe that it's essential that
frameworks are thoroughly unit tested, and that a prime goal of framework design
should be to make applications built on the framework easy to unit test.
Spring itself has an excellent unit test suite. We've found the benefits of test first
development to be very real on this project. For example, it has made working as an
internationally distributed team extremely efficient, and users comment that CVS
snapshots tend to be stable and safe to use.
We believe that applications built on Spring are very easy to test, for the following
reasons:
23
• IoC facilitates unit testing
• Applications don't contain plumbing code directly using J2EE services such as
JNDI, which is typically hard to test
• Spring bean factories or contexts can be set up outside a container
The ability to set up a Spring bean factory outside a container offers interesting
options for the development process. In several web application projects using
Spring, work has started by defining the business interfaces and
integrationtesting their implementation outside a web container. Only after business
functionality is substantially complete is a thin layer added to provide a web
interface.
Since Spring 1.1.1, Spring has provided powerful and unique support for a form of
integration testing outside the deployed environment. This is not intended as a
substitute for unit testing or testing against the deployed environment. However, it
can significantly improve productivity.
• The ability to populate JUnit test cases via Dependency Injection. This makes
it possible to reuse Spring XML configuration when testing, and eliminates the
need for custom setup code for tests.
• The ability to cache container configuration between test cases, which greatly
increases performance where slow-to-initialize resources such as
JDBC connection pools or Hibernate SessionFactories are concerned.
• Infrastructure to create a transaction around each test method and roll it back
at the conclusion of the test by default. This makes it possible for tests to
perform any kind of data access without worrying about the effect on the
environments of other tests. In my experience across several complex
projects using this functionality, the productivity and speed gain of such a
rollback-based approach is very significant.
There are many production applications using Spring. Users include investment
and retail banking organizations, well-known dotcoms, global
consultancies, academic institutions, government departments, defence contractors,
several airlines, and scientific research organizations (including CERN).
24
Many users use all parts of Spring, but some use components in isolation. For
example, a number of users begin by using our JDBC or other data access
functionality.
Roadmap
Since the first version of this article, in October 2003, Spring has progressed through
its 1.0 final release (March 2004) through version 1.l (September 2004) to 1.2 final
(May 2005). We believe in a philosophy of "release early, release often," so
maintenance releases and minor enhancements are typically released every 4-6
weeks.
We intend to continue with rapid innovation and enhancement. The next major
release will be 1.3 (final release expected Q3, 2005). Planned enhancements include:
• XML configuration enhancements (planned for release 1.3), which will allow
custom XML tags to extend the basic Spring configuration format by defining
one or more objects in a single, validated tag. This not only has the potential
to simplify typical configurations significantly and reduce configuration errors,
but will be ideal for developers of third-party products that are based on
Spring.
• Integration of Spring Web Flow into the Spring core (planned for release 1.3)
• Support for dynamic reconfiguration of running applications
• Support for the writing of application objects in languages other than Java,
such as Groovy, Jython or otherscripting languages running on the Java
platform. Such objects will benefit from the full services of the Spring IoC
container and will allow dynamic reloading when the script changes, without
affecting objects that were given references to them by the IoC container.
25
the Spring core, while still valuable to many users. This project also serves as an
incubator, so some of this functionality will probably eventually migrate into the
Spring core. Spring Modules presently includes areas such as integration with
the Lucene search engine and OSWorkflow workflow engine, a declarative, AOP-
based caching solution, and integration with the Commons Validator framework.
Interestingly, although the first version of this article was published six months
before the release of Spring 1.0 final, almost all the code and configuration examples
would still work unchanged in today's 1.2 release. We are proud of our excellent
record on backward compatibility. This demonstrates the ability of Dependency
Injection and AOP to deliver a non-invasive API, and also indicates the seriousness
with which we take our responsibility to the community to provide a stable
framework to run vital applications.
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 IoCcontainer 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 greatlyimproves 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 powerful and flexible MVC web framework that is integrated
into the overall IoC container.
26
Spring MVC Introduction
In this example we will give you quick overview of Spring MVC Framework. The
Spring MVC framework is the MVC stack for the development of web applications
based Model View Controller (MVC) architecture.
The MVC or Model View Controller architecture is famous design pattern used in
designing the applications. This design pattern separates the application into three
parts called Model, View and Controller.
Model: Model is the business data or simple the data of the application.
View: View is the presentation part of the application such as data entry form,
reports etc.
Spring MVC
The Spring MVC is a web development framework based on the MVC (Model View
Controller) design pattern. The features of Spring MVC framework are the Pluggable
View technology and Injection of services into controllers. Let's see in detail:
There are many view technologies such as JSP, Tiles, Velocity etc. Spring framework
allows us to use these view technologies.
The IoC container provides the important functionality of the dependency injection.
This helps the programmer to inject the dependency such as business service at
runtime. This saves lot of code duplication and coding effort.
Model:
27
The class org.springframework.ui.ModelMap is used by the spring framework to hold
the data. It wraps the business data into org.springframework.ui.ModelMap class and
then pass it to the view.
View:
Framework provides pluggable view, and it allows the developers to create views
using jsp, Velocity and Jasper templates. In Spring MVC Logical view and Model are
represented in the object of
the classorg.springframework.web.servlet.ModelAndView.
Controller:
The controller is responsible for handling all the requests from the user and then
process the user request. Here are the list of controllers available in the Spring 2.5
framework:
1. SimpleFormController
2. AbstractController
3. AbstractCommandController
4. CancellableFormController
5. AbstractCommandController
6. MultiActionController
7. ParameterizableViewController
8. ServletForwardingController
9. ServletWrappingController
10. UrlFilenameViewController
11. AbstractController
12. AbstractCommandController
13. SimpleFormController
14. CancellableFormController.
In the next sections we will see the examples of all these controllers.
In this we will see the request flow for the spring framework. We will also show you
the request flow diagram illustrating the working of Spring MVC module.
The Spring MVC modules comes with the Spring Framework distribution. The Spring
MVC modules of the Spring Framework well integrates with rest of the framework.
This modules is also very extensible.
Spring MVC is based on the MVC design pattern. Here is the list of key classes
of Spring MVC.
• DispatcherServlet
The DispatcherServlet is configured in the web.xml file and required URL
28
patterns are mapped to this Servlet. It works as the front controller and
handle all the request from the user.
• ModelAndView
This class works as the holder for both Model and View in the Spring MVC.
• SimpleFormController
The SimpleFormController is the Concrete FormController implementation. It
provides the configurable form and success views, and an onSubmit chain for
convenient overriding. Automatically resubmits to the form view in case of
validation errors, and renders the success view in case of a valid submission.
Let's understand the sequences of the events happens when a request is received by
the Spring MVC. Following events happens when DispatcherServlet receives are
request:
Spring MVC is request driven and DispatcherServlet handles the request from client
and then dispatches the request to controllers. It tightly integrates with the Spring
IoC container and allows the developers to use every features of Spring framework.
29
the configuration file or from the annotated controller list. < Then
DispatcherServlet dispatch the request to the appropriate Controller. The
Handler Adapters involves in this process.
4. Then the Controller processes the Client Request, it executes the logic defined
in the Controller method and finally returns the ModelAndView object back to
the Front Controller.
5. Based on the values in the ModelAndView Controller resolves the actual view,
which can be JSP, Velocity, FreeMaker, Jasper or any other configured view
resolver.
6. Then the selected view is rendered and output is generated in the form of
HttpServletResponse. Finally Controller sends the response to the
Servlet container, which sends the output to the user.
In the next section we will see the controller stack in Spring MVC
In this we will will understand the controllers hierarchy in Spring MVC Module. The
Spring MVC module provides a lot offlexibility to easily develop MVC based web
applications. It provides many controllers that can be used to achieve different jobs.
Spring MVC module is based on the MVC design pattern. The main components
involved are DispatcherServlet, Controller and Views. In Spring MVC
DispatcherServlet plays very important role. It handles the user request and
delegates it with Controller. Following diagram shows the very simplified
architecture:
In this Spring MVC, DispatcherServlet works as the controller and it delegates the
request to the Controller. Developers extends the abstract controller provided by the
framework and writes the business logic there. The actual business related
processing is done in the Controller.
30
Spring MVC provides many abstract controllers, which is designed for specific tasks.
Here is the list of anstractcontrollers that comes with the Spring MVC module:
1. SimpleFormController
2. AbstractController
3. AbstractCommandController
4. CancellableFormController
5. AbstractCommandController
6. MultiActionController
7. ParameterizableViewController
8. ServletForwardingController
9. ServletWrappingController
10. UrlFilenameViewController
11. AbstractController
12. AbstractCommandController
13. SimpleFormController
14. CancellableFormController.
31
In the next sections we will be learning about all these controllers. We will also
provide you the examples codes illustrating the usage of these controllers.
32
In this we will quickly start developing the application using Spring MVC module. We
will also see what all configuration and code is to be developed. We we will also see
how to compile, run the example program.
We will first develop a simple Spring MVC Hello World example and then test on the
Tomcat server.
What is required?
In order to complete the tutorial you will need the following software and libraries.
Getting stated:
Please make sure that JDK is installed on your computer. Check your Eclipse IDE
version, if it is not 3.3 or above download it from the official
website at http://www.eclipse.org/downloads/. Also download Spring 2.5.
We are going to develop a very simple example that will just print "Hello World"
message on the browser. We will use Eclipse IDE to develop run and test the
application.
In the next section we will create new project in eclipse and add spring libraries.
33
persisting your data to a database. Spring framework can be used in modular
fashion, it allows to use in parts and leave the other components which is not
required by the application.
Spring Architecture
1. Spring AOP
One of the key components of Spring is the AOP framework. AOP is
used in Spring:
• To provide declarative enterprise services, especially as a
replacement for EJB declarative services. The most important
such service is declarative transaction management, which
builds on Spring's transaction abstraction.
• To allow users to implement custom aspects, complementing
their use of OOP with AOP
2. Spring ORM
The ORM package is related to the database access. It provides
integration layers for popular object-relational mapping APIs,
including JDO, Hibernate and iBatis.
3. Spring Web
The Spring Web module is part of Spring’s
web application development stack, which includes Spring MVC.
34
4. Spring DAO
The DAO (Data Access Object) support in Spring is primarily for
standardizing the data access work using the technologies like JDBC,
Hibernate or JDO.
5. Spring Context
This package builds on the beans package to add support for message
sources and for the Observer design pattern, and the ability
for application objects to obtain resources using a consistent API.
7. Spring Core
The Core package is the most import component of the Spring
Framework.
This component provides the Dependency Injection features. The
BeanFactory provides a factory pattern which separates the
dependencies like initialization, creation and access of the objects
from your actual program logic.
35
Spring Framework Architecture
Once extract go to the extracted folder and you will find many files.
• build.bat
36
• build.xml
• build-continuous.xml
• changelog.txt
• license.txt
• maven.xml
• notice.txt
• project.properties
• readme.txt
• tests.bat
The dist directory of the spring framework contains the spring modules (modules
directory) library files. We are mostly concern with these jar files. We will copy
these jar files into our development environment. These jar files are:
• spring-aop.jar
• spring-beans.jar
• spring-context.jar
• spring-context-support.jar
37
• spring-core.jar
• spring-jdbc.jar
• spring-jms.jar
• spring-orm.jar
• spring-test.jar
• spring-tx.jar
• spring-web.jar
• spring-webmvc.jar
• spring-webmvc-portlet.jar
• spring-webmvc-struts.jar
Another most important directory is "lib", which contains required library files for
the application.
The following libraries are included in the Spring Framework distribution because
they are required either for building the framework or for running the sample apps.
Note that each of these libraries is subject to the respective license; check the
respective project distribution/website before using any of them in your own
applications.
* antlr/antlr-2.7.6.jar
- ANTLR 2.7.6 (http://www.antlr.org)
- required for running PetClinic (by Hibernate)
* aopalliance/aopalliance.jar
- AOP Alliance 1.0 (http://aopalliance.sourceforge.net)
- required for building the framework
- included in spring.jar and spring-aop.jar
NOTE: aspectjtools.jar is not included in the Spring distribution because of its size.
It needs to be taken from the AspectJ distribution or from Spring CVS. Note that this
is only necessary if you want to rebuild the Spring jars including the AspectJ aspects.
* axis/axis.jar, axis/wsdl4j.jar
- Apache Axis 1.4 (http://ws.apache.org/axis)
- required for building the framework
- required for running JPetStore
* bsh/bsh-2.0b4.jar
- BeanShell 2.0 beta 4 (http://www.beanshell.org)
- required for building the framework
38
- required at runtime when using Spring's BeanShell support
* bnd/bnd.jar
- BND tool 0.0.208 (http://www.aqute.biz/Code/Bnd)
- required for adding OSGi entries to the jar manifests at build time
* c3p0/c3p0-0.9.1.2.jar
- C3P0 0.9.1.2 connection pool (http://sourceforge.net/projects/c3p0)
- required for building the framework
- required at runtime when using Spring's C3P0NativeJdbcExtractor
- required for running Image Database
* caucho/hessian-3.1.3.jar
- Hessian/Burlap 3.1.3 (http://www.caucho.com/hessian)
- required for building the framework
- required at runtime when using Spring's Hessian/Burlap remoting support
* cglib/cglib-nodep-2.1_3.jar
- CGLIB 2.1_3 with ObjectWeb ASM 1.5.3 (http://cglib.sourceforge.net)
- required for building the framework
- required at runtime when proxying full target classes via Spring AOP
* commonj/commonj-twm.jar
- CommonJ TimerManager and WorkManager API 1.1
(http://dev2dev.bea.com/wlplatform/commonj/twm.html)
- required for building the framework
- required at runtime when using Spring's CommonJ support
* concurrent/backport-util-concurrent.jar
- Dawid Kurzyniec's JSR-166 backport, version 3.0
(http://dcl.mathcs.emory.edu/util/backport-util-concurrent)
- required for building the framework
- required at runtime when using Spring's backport-concurrent support
* dom4j/dom4j-1.6.1, dom4j/jaxen-1.1-beta-7.jar
- DOM4J 1.6.1 XML parser (http://www.dom4j.org)
- required for running PetClinic (by Hibernate)
* easymock/easymock.jar, easymock/easymockclassextension.jar
- EasyMock 1.2 (JDK 1.3 version) (http://www.easymock.org)
- required for building and running the framework's test suite
* ehcache/ehcache-1.3.0.jar
- EHCache 1.3.0 (http://ehcache.sourceforge.net)
- required for building the framework
- required at runtime when using Spring's EHCache support
- required for running PetClinic (by Hibernate)
* freemarker/freemarker.jar
- FreeMarker 2.3.11 (http://www.freemarker.org)
- required for building the framework
- required at runtime when using Spring's FreeMarker support
39
* glassfish/glassfish-clapi.jar
- GlassFish ClassLoader API extract (http://glassfish.dev.java.net)
- required for building the framework
* groovy/groovy-1.5.1.jar
- Groovy 1.5.1 (http://groovy.codehaus.org)
- required for building the framework
- required at runtime when using Spring's Groovy support
* hibernate/hibernate3.jar
- Hibernate 3.2.5 (http://www.hibernate.org)
- required for building the framework
- required at runtime when using Spring's Hibernate support
* hibernate/hibernate-annotation.jar
- Hibernate Annotations 3.3.0 (http://www.hibernate.org)
- required for building the "tiger" part of the framework
- required at runtime when using Spring's Hibernate Annotations support
* hibernate/hibernate-entitymanager.jar
- Hibernate EntityManager 3.3.1 (http://www.hibernate.org)
- required for building the "tiger" part of the framework
- required at runtime when using Spring's Hibernate-specific JPA support
* hibernate/jboss-archive-browsing.jar
- JBoss Archive Browsing 5.0.0 alpha
- required at runtime when using Hibernate EntityManager
* hsqldb/hsqldb.jar
- HSQLDB 1.8.0.1 (http://hsqldb.sourceforge.net)
- required for running JPetStore and PetClinic
* ibatis/ibatis-2.3.0.677.jar
- iBATIS SQL Maps 2.3.0 b677 (http://ibatis.apache.org)
- required for building the framework
- required at runtime when using Spring's iBATIS SQL Maps 2.x support
* itext/iText-2.0.7.jar
- iText PDF 2.0.7 (http://www.lowagie.com/itext)
- required for building the framework
- required at runtime when using Spring's AbstractPdfView
* j2ee/activation.jar
- JavaBeans Activation Framework 1.1
(http://java.sun.com/products/javabeans/glasgow/jaf.html)
- required at runtime when using Spring's JavaMailSender on JDK < 1.6
* j2ee/common-annotations.jar
- JSR-250 Common Annotations (http://jcp.org/en/jsr/detail?id=250)
- required at runtime when using Spring's Common Annotations support on JDK <
1.6
* j2ee/connector.jar
40
- J2EE Connector Architecture 1.5 (http://java.sun.com/j2ee/connector)
- required for building the framework
* j2ee/ejb-api.jar
- Enterprise JavaBeans API 3.0 (http://java.sun.com/products/ejb)
- required for building the framework
- required at runtime when using Spring's EJB support
* j2ee/el-api.jar
- JSP 2.1's EL API (http://java.sun.com/products/jsp), as used by JSF 1.2
- required for building the framework
- required at runtime when using Spring's JSF 1.2 support
* j2ee/jaxrpc.jar
- JAX-RPC API 1.1 (http://java.sun.com/xml/jaxrpc)
- required for building the framework
- required at runtime when using Spring's JAX-RPC support
* j2ee/jms.jar
- Java Message Service API 1.1 (java.sun.com/products/jms)
- required for building the framework
- required at runtime when using Spring's JMS support
* j2ee/jsf-api.jar
- JSF API 1.1 (http://java.sun.com/j2ee/javaserverfaces)
- required for building the framework
- required at runtime when using Spring's JSF support
* j2ee/jsp-api.jar
- JSP API 2.0 (http://java.sun.com/products/jsp)
- required for building the framework
- required at runtime when using Spring's JSP support
* j2ee/jstl.jar
- JSP Standard Tag Library API 1.1 (http://java.sun.com/products/jstl)
- required for building the framework
- required at runtime when using Spring's JstlView
* j2ee/jta.jar
- Java Transaction API 1.1 (http://java.sun.com/products/jta)
- required for building the framework
- required at runtime when using Spring's JtaTransactionManager
* j2ee/mail.jar
- JavaMail 1.4 (http://java.sun.com/products/javamail)
- required for building the framework
- required at runtime when using Spring's JavaMailSender
* j2ee/persistence.jar
- Java Persistence API 1.0
(http://www.oracle.com/technology/products/ias/toplink/jpa)
- required for building the framework
- required at runtime when using Spring's JPA support
41
* j2ee/rowset.jar
- JDBC RowSet Implementations 1.0.1 (http://java.sun.com/products/jdbc)
- required at runtime when using Spring's RowSet support on JDK < 1.5
* j2ee/servlet-api.jar
- Servlet API 2.4 (http://java.sun.com/products/servlet)
- required for building the framework
- required at runtime when using Spring's web support
* jakarta-commons/commons-attributes-api.jar, jakarta-commons/commons-
attributes-compiler.jar
- Commons Attributes 2.2 (http://jakarta.apache.org/commons/attributes)
- commons-attributes-api.jar has a patched manifest (not declaring QDox and Ant as
required extensions)
- required for building the framework
- required at runtime when using Spring's Commons Attributes support
* jakarta-commons/commons-beanutils.jar
- Commons BeanUtils 1.7 (http://jakarta.apache.org/commons/beanutils)
- required for running JPetStore's Struts web tier
* jakarta-commons/commons-collections.jar
- Commons Collections 3.2 (http://jakarta.apache.org/commons/collections)
- required for building the framework
- required for running PetClinic, JPetStore (by Commons DBCP, Hibernate)
* jakarta-commons/commons-dbcp.jar
- Commons DBCP 1.2.2 (http://jakarta.apache.org/commons/dbcp)
- required for building the framework
- required at runtime when using Spring's CommonsDbcpNativeJdbcExtractor
- required for running JPetStore
* jakarta-commons/commons-digester.jar
- Commons Digester 1.6 (http://jakarta.apache.org/commons/digester)
- required for running JPetStore's Struts web tier
* jakarta-commons/commons-discovery.jar
- Commons Discovery 0.2 (http://jakarta.apache.org/commons/discovery)
- required for running JPetStore (by Axis)
* jakarta-commons/commons-fileupload.jar
- Commons FileUpload 1.2 (http://jakarta.apache.org/commons/fileupload)
- required for building the framework
- required at runtime when using Spring's CommonsMultipartResolver
* jakarta-commons/commons-httpclient.jar
- Commons HttpClient 3.1 (http://hc.apache.org/httpclient-3.x)
- required for building the framework
- required at runtime when using Spring's CommonsHttpInvokerRequestExecutor
* jakarta-commons/commons-io.jar
- Commons IO 1.3.1 (http://jakarta.apache.org/commons/io)
42
- required at runtime when using Spring's CommonsMultipartResolver (by Commons
FileUpload)
* jakarta-commons/commons-lang.jar
- Commons Lang 2.2 (http://jakarta.apache.org/commons/lang)
- required at runtime when using Spring's OpenJPA support (by OpenJPA)
* jakarta-commons/commons-logging.jar
- Commons Logging 1.1 (http://jakarta.apache.org/commons/logging)
- required for building the framework
- required at runtime, as Spring uses it for all logging
* jakarta-commons/commons-pool.jar
- Commons Pool 1.3 (http://jakarta.apache.org/commons/pool)
- required for running JPetStore and Image Database (by Commons DBCP)
* jakarta-commons/commons-validator.jar
- Commons Validator 1.1.4 (http://jakarta.apache.org/commons/validator)
- required for running JPetStore's Struts web tier on servers that eagerly load tag
libraries (e.g. Resin)
* jakarta-taglibs/standard.jar
- Jakarta's JSTL implementation 1.1.2 (http://jakarta.apache.org/taglibs)
- required for running JPetStore, PetClinic, Countries
* jamon/jamon-2.4.jar
- JAMon API (Java Application Monitor) 2.4 (http://www.jamonapi.com)
- required for building the framework
- required at runtime when using Spring's JamonPerformanceMonitorInterceptor
* jarjar/jarjar.jar
- Jar Jar Links 1.0 RC5 (http://code.google.com/p/jarjar)
- required for building the framework jars
* jasperreports/jasperreports-2.0.2.jar
- JasperReports 2.0.2 (http://jasperreports.sourceforge.net)
- required for building the framework
- required at runtime when using Spring's JasperReports support
* jdo/jdo2-api.jar
- JDO API 2.0 (http://db.apache.org/jdo)
- required for building the framework
- required at runtime when using Spring's JDO support (or jdo.jar for JDO 1.0)
* jexcelapi/jxl.jar
- JExcelApi 2.6.6 (http://jexcelapi.sourceforge.net)
- required for building the framework
- required at runtime when using Spring's AbstractJExcelView
43
* jmx/jmxri.jar
- JMX 1.2.1 reference implementation
- required at runtime when using Spring's JMX support on JDK < 1.5
* jmx/jmxremote.jar
- JMX Remote API 1.0.1 reference implementation
- required at runtime when using Spring's JMX support on JDK < 1.5
* jmx/jmxremote_optional.jar
- JMXMP connector (from JMX Remote API 1.0.1 reference implementation)
- required at runtime when using the JMXMP connector (even on JDK 1.5)
* jotm/jotm.jar
- JOTM 2.0.10 (http://jotm.objectweb.org)
- required for building the framework
- required at runtime when using Spring's JotmFactoryBean
* jotm/xapool.jar
- XAPool 1.5.0 (http://xapool.experlog.com, also included in JOTM)
- required for building the framework
- required at runtime when using Spring's XAPoolNativeJdbcExtractor
* jruby/jruby.jar
- JRuby 1.0.1 (http://jruby.codehaus.org)
- required for building the framework
- required at runtime when using Spring's JRuby support
* junit/junit-3.8.2.jar, junit/junit-4.4.jar
- JUnit 3.8.2 / 4.4 (http://www.junit.org)
- required for building and running the framework's test suite
* log4j/log4j-1.2.14.jar
- Log4J 1.2.14 (http://logging.apache.org/log4j)
- required for building the framework
- required at runtime when using Spring's Log4jConfigurer
* oc4j/oc4j-clapi.jar
- Oracle OC4J 10.1.3.1 ClassLoader API extract
(http://www.oracle.com/technology/tech/java/oc4j)
- required for building the framework
* openjpa/openjpa-1.0.1.jar
- OpenJPA 1.0.1 (http://openjpa.apache.org)
- required for building the framework
- required at runtime when using Spring's JPA support with OpenJPA as provider
* poi/poi-3.0.1.jar
- Apache POI 3.0.1 (http://jakarta.apache.org/poi)
- required for building the framework
- required at runtime when using Spring's AbstractExcelView
* portlet/portlet-api.jar
- Portlet API 1.0 (http://jcp.org/aboutJava/communityprocess/final/jsr168)
44
- required for building the framework
- required at runtime when using Spring's Portlet support
* qdox/qdox-1.5.jar
- QDox 1.5 (http://qdox.codehaus.org)
- used by Commons Attributes 2.2 to parse source-level metadata in the build
process
- required for building the framework and the attributes version of JPetStore
* quartz/quartz-all-1.6.0.jar
- Quartz 1.6.0 (http://www.opensymphony.com/quartz)
- required for building the framework
- required at runtime when using Spring's Quartz scheduling support
* serp/serp-1.13.1.jar
- Serp 1.13.1 (http://serp.sourceforge.net)
- required at runtime when using OpenJPA
* struts/struts.jar
- Apache Struts 1.2.9 (http://jakarta.apache.org/struts)
- required for building the framework
- required at runtime when using the Struts 1.x support or Tiles 1.x TilesView
- required for running JPetStore's Struts web tier
* testng/testng-5.5-jdk15.jar
- TestNG 5.5 (http://testng.org)
- required for building and running the framework's test suite
* tomcat/catalina.jar, tomcat/naming-resources.jar
- Apache Tomcat 5.5.23 (http://tomcat.apache.org)
- required for building the Tomcat-specific weaver
* toplink/toplink-api.jar
- Oracle TopLink 10.1.3 API
(http://www.oracle.com/technology/products/ias/toplink)
- required for building the framework
- replaced with full toplink.jar at runtime when using Spring's TopLink support
* toplink/toplink-essentials.jar
- Oracle TopLink Essentials v2 b41
(http://www.oracle.com/technology/products/ias/toplink/jpa)
- required for building the framework
- required at runtime when using Spring's JPA support with TopLink as provider
* velocity/velocity-1.5.jar
- Velocity 1.5 (http://jakarta.apache.org/velocity)
- required for building the framework
- required at runtime when using Spring's VelocityView
45
* velocity/velocity-tools-view-1.4.jar
- Velocity Tools 1.4 (http://jakarta.apache.org/velocity/tools)
- required for building the framework
- required at runtime when using VelocityView's support for Velocity Tools
You can use above libraries in your application as per your requirement.
In the next section I will show you how to setup development environment step-by-
step.
XML Bean-Injection, The given example below gives the brief description of
the extension name spaces that can be used in the spring framework With the use of
extensible name space you can make Spring configuration file more simpler to use
for many tasks which can occurs repeatedly . Extension namespaces also allows us
to supply property values by using attributes .
xmlns:p="http://www.springframework.org/schema/p":-Here we have
introduced namespace:"p" that cannot be validated.
p:name="Girish" :-Here we simply use the property name in the "p" namespace,
as in "p:name".
context.xml
46
p:email="[email protected]"/>
</beans>
Main.java
This is the file through which we are retrieving the property of the
bean defined above. Some of the methods which are used here are as follows:-
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
class Inject {
47
public void setEmail(String email) {
this.email = email;
}
@Override
public String toString() {
return String.format("Name: %s\n" +
"Age: %d\n" +
"Address: %s\n" +
"Company: %s\n" +
"E-mail: %s",
this.name, this.age, this.address, this.company, this.em
ail);
}
}
48
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"/>
</bean>
</beans>
Main.java
ApplicationContext ac = new
ClassPathXmlApplicationContext("context.xml", Main.class):-
ApplicationContext is the interface that is used to provide Bean factory methods for
accessing application components. Here we Creates an instance of this interface to
access context.xml and Main.java.
import javax.sql.DataSource;
import org.springframework.context.ApplicationContext;
import
org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jdbc.core.JdbcTemplate;
class Main {
public static void main(String args[]) {
try {
ApplicationContext ac = new
ClassPathXmlApplicationContext("context.xml",
Main.class);
DataSource source = (DataSource)
ac.getBean("dataSource");
JdbcTemplate jt = new JdbcTemplate(source);
jt.batchUpdate(new String[]{"update employee set
departement = 'Finance#'",
"delete from employee where EmployeeId =31"
});
System.out.println("Data updated successfully");
} catch (Exception e) {
e.printStackTrace();
}
}
}
49
Data updated successfully
BUILD SUCCESSFUL (total
time: 2 seconds)
Inheritance in Spring
Inheritance Demo, In the example given below we are going to tell about
the inheritance in the Spring framework. Byinheritance we mean a way of forming
new classes using classes that have already been defined. Here we have created a
simple bean and used this bean as a template for creating other beans.
</bean>
<bean id="child" class="mybean" parent="parent">
<property name="address" value="Rohini"/>
</bean>
context.xml
50
<bean id="subchild" class="mybean" parent="parent"/>
</beans>
Main.java
This is the file through which we are retrieving the property of the
bean defined above. Some of the methods which are used here are as follows:-
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
}
}
class mybean {
private String name;
private String address;
51
}
@Override
public String toString() {
final StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("Bean");
stringBuilder.append("{name='").append(name).append('\'');
stringBuilder.append(", address=").append(address);
stringBuilder.append('}');
return stringBuilder.toString();
}
}
Hello World Example using Spring, The tutorial given below describes you the way
to make a spring web application that displays Hello World message on the Browser.
For that we have created a file called "applicationContext.xml", which defines the
bean name, their properties as well as their values.
Required fields:-
1)class name: A class name is the implementation of the bean class that is
described in the bean definition.
2)bean behavioral configuration elements: Here we define the bean behavior
that is bean initialization, dependencychecking mode, destruction methods etc.
3)constructor arguments and property values :-Defines the no
of arguments and the property values that are to be set in the newly created bean.
Note:- We have not defined any of these behavior in our context file since we
haven't created any of the bean to be used.
52
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
</beans>
dispatcher-servlet. xml:-This is the file from which the mapping from actions to
controllers is done .We have used ControllerClassNameHandlerMapping and
SimpleUrlHandlerMapping classes to do such mapping.
ControllerClassNameHandlerMapping class generate URL path mappings from the
class names of the Controller.SimpleUrlHandlerMapping maps URLs to the request
handler beans.
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
<bean class="org.springframework.web.servlet.mvc.support.ControllerC
lassNameHandlerMapping"/>
<bean id="urlMapping" class="org.springframework.web.servlet.handler
.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/index.htm">indexController
</prop>
</props>
</property>
</bean>
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceVi
53
ewResolver"
p:prefix="/WEB-INF/jsp/"
p:suffix=".jsp" />
<bean name="indexController"
class="org.springframework.web.servlet.mvc.ParameterizableView
Controller"
p:viewName="index" />
</beans>
redirect.jsp:-
<%Â response.sendRedirect("index.htm");Â %>:-This is a method of
Interface HttpServletResponse that is used to sends a temporary redirect response
to the client using the specified redirect location.
<body>
<h2>Hello World</h2>
</body>
</html>
In the given example you will be learning about a constructor and how to call a
constructor in the Spring. Declaring constructor injection in the Spring framework is
generally done in the bean section of the configuration file that is the context.xml
file.
54
2)Pass the value to the constructor.
This tutorial describes the way of defining constructor in the xml document and
retrieving the values defined in the constructor using java file.
<constructor-arg>
<util:map>
<entry key="CompanyName" value="javabeat.net"/>
<entry key="Address" value="Rohini"/>
</util:map>
</constructor-arg>
context.xml
<bean id="encyclopedia"
name="mybean"
class="Configure">
<constructor-arg>
<util:map>
<entry key="CompanyName" value="javabeat.net"/>
<entry key="Address" value="Rohini"/>
</util:map>
</constructor-arg>
</bean>
Here is the file named Main.java through which we are retrieving the properties of
the bean which we have defined in the above file i.e. context.xml
55
XmlBeanFactory factory = new XmlBeanFactory(new ClassPathResource("c
ontext.xml")):-Here we are creating an instance of the XmlBeanFactory which is
used to read bean definition from an XML document
new ClassPathResource("context.xml"):-Creates a new ClassPathResource for
ClassLoader .Here the context.xml is the file which is to be loaded.
Main.java
import java.util.Map;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.util.Assert;
interface company {
String Name();
String address();
}
interface Detail {
56
}
}
class Configure implements Detail {
Calling Bean using init() method in Spring, this section describes the way to initialize
a bean through its lifecycleevents using the init() method .Here we have defined the
property and values of the bean using the init method as shown below:-
<property name="name">
57
<value>javabeat.net</value>
</property>
<property name="address">
<value>Rohini</value>
</property>
<property name="type">
<value>Software Development Company</value>
</property>
</bean>
initMethod.xml
Here is the file named SimpleBean.java through which we are retrieving the
properties of the bean which we havedefined in the above file i.e. initMethod.xml.
SimpleBean.java
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.FileSystemResource;
58
this.name = name;
}
public void setAddress(String address) {
this.address = address;
}
if (name == null) {
System.out.println("Using default name");
name = DEFAULT_NAME;
}
if (address == null) {
System.out.println("Using default name");
address = DEFAULT_NAME;
}
if (type == null) {
System.out.println("Using default name");
type = DEFAULT_NAME;
}
}
public String toString() {
return "Name: " + name + "\nAddress: " + address + "\nType: " +
type ;
}
Initializing bean
59
Name: javabeat.net
Address: Rohini
Type: Software
Development Company
Here "Bean" is the name of the bean class which would be further referred in
the xml file with the id "MyBean".
context.xml
Here is the file named Main.java through which we are retrieving the properties of
the bean which we have defined in the above file i.e. context.xml
60
class BeanSupport implements InitializingBean :-Here the InitializingBean
interface is implemented by bean class. The use of this interface here is to do some
post processing actions when all the properties have been set by the Bean Factory..
@Override
public String toString() { return String.format("%s : \"%s\"", th
is.company, getValue());
}
Here the method toString() is overridden which is returning the the company name
and value that has been defined in the context.xml file.
Main.java
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
System.out.println(factory.getBean("Mybean"));
}
}
class Bean extends BeanSupport {
61
}
62