Vous êtes sur la page 1sur 6

The Spring Framework

by Benoy Jose

Introduction
Officially the spring season might be over but spring still seems to be lingering around. If you did not
get the smell of the Spring Framework this summer then you might be missing something. You might
be having your fingers crossed skeptically about another run of the mill Framework system that we
have been seeing for the last couple of years. Hundreds of open source and propriety frameworks
have sprung all over the place making it difficult to identify what each framework does, so the
skepticism is understandable, but before we write off spring like one of those others it might be worth
briefly peeking through it. Spring proposes a new paradigm, a pluggable, non- intrusive and robust
framework.

Summary
Unlike other frameworks and APIs, spring does not impose itself wholly on to the design of a project.
Spring is modular and has been divided logically into independent packages, which can function
independently. The architects of an application have the flexibility to implement just a few spring
packages and leave out most of the packages in spring. The "Spring Framework" would not feel bad
with this attitude and on the contrary encourages users to introduce Spring into existing applications in
a phased manner. So no matter what kind of framework you are using now Spring will co-exist with it
without causing you nightmares and further more Spring will allow you to choose specific packages in
Spring.

The "Struts" framework is no doubt a good framework to enhance the ability of the web tier, but the
biggest drawback is the fact that it caters only to the web tier and leaves most of the Enterprise tier or
middle tier to the fancy of the application architects. The Application architects need to provide an
additional framework to deal with the enterprise tier and make sure that the new framework integrates
well with the Struts framework. Spring tries to alleviate this problem by providing a comprehensive
framework, which includes an MVC framework, an AOP integration framework, a JDBC integration
framework, and an EJB integration framework. It also provides integration modules for major O/R
mapping tools like Hibernate and JDO. Spring provides all these in a modular fashion without imposing
any layer on to the user. Spring is not a take-it-or- leave-it kind of framework. It tries to seamlessly
blend into the existing framework users have without hindrances. Spring also provides transaction
management support using Java classes, email support packages using framework classes, web
services support through proxies and many more features like the above. As mentioned earlier all
these packages are optional and spring does not make any of them mandatory. Spring can seamlessly
integrate with existing applications and provide specific functionality that you intend to provide with
minimal demands for customization. A user can continue to use Struts for the web tier and toplink O/R
for the database and meanwhile hook spring to provide e-mail services and web services support.
Spring is based on the Inversion of Control/Dependency Injection pattern that has been making rounds
in message boards all over the Internet.

Inversion of Control/Dependency Injection


Dependency injection is kind of an Inversion of Control pattern. It is proposed as an alternative for the
Service Locator. Martin flower discusses the Dependency Injection pattern, Inversion of Control pattern
and the differences it has with the service locator in an article at his site (See resources below).

Dependency Injection proposes separating the implementation of an object and the construction of
objects that depend on them. The job of coordinating the implementation and construction is left to the
Assembler code. The object that needs to be implemented does not need to instantiate the dependent
objects and can rely on the assembler to do the job. The assembler will gather and instantiate, if
necessary, all the dependent objects and make them available to the implemented object. Since the
assembler does not depend on the code directly changes can be made to the assembler without any
changes to the code. The assembler gathers the required classes through configuration files so a
change in the assembler only needs changes to the configuration file. In this case the Assembler code
would be the spring framework.

Since the classes are independent and are integrated through the assembler, independent testing of
each class can be done without affecting other application codes.

There are three types of Dependency Injections.

Type 1 IOC also called Interface Injection In Type 1 IOC the injection is done though an interface.
The interface will define the injection method and the implementation class has to implement this
interface and provide concrete implementation for the injection method.
Type 2 IOC also called Setter Injection In Type 2 IOC the injection is done via a setter method.
Type 2 IOC uses setter methods to get the dependent classes it needs.
Type 3 IOC also called Constructor Injection. In Type 3 IOC implementing class defines a
constructor to get all its dependents. The dependent classes are defined in the constructor arguments.

How does Spring Work?


The idea is that beans follow the Dependency Injection pattern. Beans have information on the classes
dependent on them. Beans define their own attributes within bean descriptors and also define the
beans they depend on in the same descriptors. The Bean does not need to locate and instantiate
these classes using service locators or JNDI calls. The Assembler (Spring Framework in this case)
takes care of finding these classes based on the information provided in the descriptor and makes
them available to the calling class. The service locator pattern does almost the same job, so why do
we need another pattern to do it. The class that needs the dependent classes needs to tell the Service
Locator as to which classes are required by it and moreover the responsibility of finding these classes
and invoking them falls on the calling class. This makes the classes tightly coupled with each other
making them difficult to unit test them separately. In the case of the Dependency Injection pattern the
responsibility is shifted to the Assembler to load these classes. The assembler can make changes to
the dependent classes by simply modifying the descriptor file. Martin Flower’s article in the resources
shows the comparison between Dependency Injection and Service Locator with a good example.

Beans, BeanFactory and Application Context


The basic package in the spring framework is the org.springframework.beans package. Spring
framework uses JavaBeans and this package provides most of the basic functionality to manipulate
Java beans and provides the basic infrastructure for the other spring framework classes. This package
also provides the basis for the "Dependency injection" pattern that Spring is based on.

There are two ways in which clients can use the functionality of the Spring Framework--the
BeanFactory and the ApplicationContext. The BeanFactory is a generic factory, which stores the
information about all the Spring Beans and allows the user to instantiate beans and manage them. The
BeanFactory provides programmers with the facilities to implement the basic features of the Spring
Framework. The ApplicationContext builds on top of the BeanFactory and inherits all the basic features
of the Spring Framework. Apart from the basic features, ApplicationContext provides additional
features like Event management, internationalization support and resource management.

The BeanFactory is particularly useful in low memory situations like in an Applet where having the
whole API would be overkill. It provides the basic spring framework features and does not bring all the
excess baggage that ApplicationContext has. ApplicationContext helps the user to use Spring in a
framework oriented way while the BeanFactory offers a programmatic approach.

BeanFactory
A BeanFactory is like a factory class that contains a collection of beans. The BeanFactory holds
BeanDefinitions of multiple beans within itself and then instantiates the bean whenever asked for by
clients.

XMLBeanFactory is a BeanFactory implementation provided within the Spring Framework. The


XMLBeanFactory can read BeanDefinitions from a XML file directly. The XMLBeanFactory validates
the XML using a DTD file called beans.dtd and checks for inconsistencies in the XML.

Bean Class
The Bean, which is stored in the BeanFactory, is the actual class that would carry the logic for the
bean. Spring does not define any standards on how the bean needs to be structured. Any J2EE
complaint bean structure is acceptable to Spring. Unlike Struts and other frameworks the beans do not
need to implement any special Spring interfaces to make them work in the Spring Framework.
Depending upon the kind of Inversion required the bean might have to follow the rules of the
corresponding Inversion Dependency pattern. Spring supports only Constructor based injection and
setter based injection. So a bean that used constructor-based injection should have to define
constructors accordingly. Spring recommends setter-based injection over constructor-based injection
as multiple constructors can make the bean huge and unmanageable.

A bean has one or more IDs associated with it. The ID should be unique within the BeanFactory it is
contained in so that the BeanFactory can look up the bean using the ID. If a bean has multiple IDs
they are defined as aliases for the bean.

The spring framework takes care of how the beans can be created and sent back to clients. Beans can
be deployed as singletons or as non-singletons. If a bean is defined as a singleton then only one
instance of the bean is created by the BeanFactory and returned when a request for the bean is made.
All subsequent requests get the same instance which was created first. Non- singleton beans or
Prototype beans can have multiple instances created. So each time a request is made for a bean to
the BeanFactory a new instance is created and returned. The BeanFactory cannot do Lifecycle
management of a prototype bean, as a new instance is created for each client who requests
it(Lifecycle management of a bean is discussed in a subsequent section).

BeanDefinition
The BeanDefinition contains all the information required by the BeanFactory to instantiate the bean.
This includes any dependencies the bean may have on other beans and how the bean needs to be
configured in the container. When a request is made for a bean, the BeanFactory loads the
corresponding BeanDefinition and instantiates the bean. The BeanDefinition has information on how
the bean would be instantiated (Singleton or prototype) and callback methods defined in the Lifecycle
section.

Lifecycle of a Bean
After the bean is initialized the BeanFactory can use callback methods to change the behavior of the
bean in the BeanFactory. One of the callback methods is the init-method. The InitializingBean interface
of the factory package gives the ability to do initialization work after properties are set up for a bean in
the BeanFactory. The afterPropertiesSet () method in the InitializingBean interface allows the user to
check if all the properties are set properly or if some operation has to be done after the properties have
been set. All Bean classes that need to use this callback method need to implement the
InitializingBean interface and implement the afterPropertiesSet () method. If the initialization work is
minimal the user has the flexibility to designate a method within the bean, which will be invoked after
bean properties have been set. The designated method, which would do the initialization, can be then
be specified in the init-method attribute of the bean. Designating the init-method attribute can help to
avoid implementing the InitializingBean interface.

In a similar fashion a DisposableBean interface is provided to do cleanup operations after a bean is


destroyed. The bean has a destroy-method attribute that can used to designate a method within the
bean, which will do the clean up work when the BeanFactory destroys the bean.

Other Features:

Spring can automatically resolve the dependent beans with the help of the BeanFactory. This
facility can reduce the need to specify properties or constructor arguments.
Spring can check dependencies on a bean. It can check for values that should be set when a
bean is initialized. If the check is not done the BeanFactory will set the default value. This behavior is
not mandatory and can be turned on when required.
Spring can also manage multiple resource files for you.

Sample
Lets go through a sample to illustrate a few of the important ideas outlined above. Shown below is a
snippet of XML that defines some BeanDefinitions of an actual bean.

<bean id = ‘helloWorldSample´
class=”com.helloworld.samples.HelloWorld”
depends-on = ”boostrapClassId”>
<property name=”myString”>
My famous Hello World Program</property>
<property name=”dependentClassId”>
<ref bean = “firstDependentClass”/>
</property>
</bean>

<bean id = “firstDependentClass”
class = “com.helloworld.dependent.FirstDependentClass”
destroy-method=”cleanupMethod”>
<property name=”dependentString”>
My famous Hello World Program needs me</property>
<bean>

<bean id = “bootstrapClassId”
class = “com.helloworld.config.BootStrapClass”
init-method = “loadPropertiesFromFile”>

The sample above shows a BeanDefinition for a HelloWorld Class, which depends upon the
BootStrapClass class. The property ‘myString’ would translate into a field into the bean with a default
value specified within it. Since the BeanFactory knows that this bean requires the class
FirstDependentClass, it would instantiate that class before it sets the reference for that class in the
main bean. The property "dependentClassId" would also become a field in the bean with a reference to
the FirstDependentClass. The loadProertiesFromFile method which is specified as a init method will be
invoked after properties have been set to the BootStrapClass bean.

Application Context
The ApplicationContext provides a framework type of API to Spring. The framework allows the user to
use a ContextLoader to load beans. The ContextLoader does the job of the BeanFactory. The
ApplicationContext provides all the features offered by BeanFactory and allows the user to add some
additional features. Some of the features offered by the ApplicationContext are MessageSources,
Resource management and Event Propagation.

MessageSource offers an i18n type messaging facility. Event Propagation allows Spring to have an
event handling mechanism. The Event handling is done via the ApplicationEvent Class and the
ApplicationListener interface. Every bean that’s wants to be notified of any events would implement the
ApplicationListener Interface. Whenever an ApplicationEvent takes place the ApplicationContext knows
about it. The ApplicationContext would notify the beans that are listening to this event.

Additional Support
Spring provides a lot of additional modules, which are optional to the framework. The User has the
flexibility to use them, as they need them in their application. Some of these features are briefly
discussed below.

Spring AOP
Spring does not need Aspect Oriented Programming (AOP) to function as a framework. AOP enhances
the Spring middleware support by providing declarative services. The declarative services can be used
as replacements for the EJB declarative services used in CMTs. The EJB "declarative services" are
provided by Spring using the "declarative transaction management service." Transaction management
services are based on the spring transaction management, which will be discussed next.

Transaction Management
Spring provides a simple programmatic transaction management API. Spring provides support for both
declarative transaction management and programmatic transaction management. Declarative
transaction management is used in EJB container managed transactions (CMT) and programmatic
transaction management is used in EJB bean managed persistence. Additionally Spring can use
transaction management to avoid the use of EJBs where not required.

Data Access using JDBC


The org.springframework.jdbc package provides all the JDBC related support required by the
application. One of the interesting interfaces within this package is the SQLExceptionTranslator. The
translator can help in providing translations from the very common and generic SQLException in to
something more specific and informative. SQLExceptions are too generic and cannot provide any
great information that can be passed back to the user. Spring’s wrapper (SQLExceptionTranslator) can
implemented specific to a vendor and can provide informative error messages, which can be sent back
to the user.

O/R Mapping
Spring provides integration with OR mapping tools like Hibernate, JDO and iBATIS. (For information on
Hibernate see resources below). Spring provides very good support for Hibernate. Spring augments
the power of Hibernate by providing support for Hibernate sessions, Hibernate transaction
management and other features in Hibernate.

Spring Web Framework


Spring provides a pluggable MVC architecture. The users have a choice to use the web framework or
continue to use their existing web framework. Spring separates the roles of the controller; the model
object, the dispatcher and the handler object which makes it easier to customize them. Spring web
framework is view agnostic and does not push the user to use only JSPs for the view. The user has the
flexibility to use JSPs, XSLT, velocity templates etc to provide the view.

Spring And EJB


In a usual EJB application EJBs are located using service locators and managed using business
delegates. These results in EJB JNDI look ups scattered all over the code. Spring can provide proxy
objects, which can act as business delegates do the same job. These proxies can be configured into
the BeanFactory and the ApplicationContext.

Conclusion
Spring is very new to the market and provides a new lease of life to framework development. Spring
does not try to duplicate existing solutions; it tries to integrate with exiting solutions like JDO, AOP and
Hibernate. However spring creates a new web framework to replace Struts, as the creators of Spring
feel that Struts is not robust enough. Spring would generate great interest in the coming months as
more people become aware of it and find it worthwhile to implement. Spring is portable across
application servers, as it does not include any application server or platform specific requirements.
This makes it compatible on major application servers like Websphere, Weblogic, Tomcat, Jboss and
others like them. As of now spring can be integrated and used in a eclipse IDE, however as the
versions improve spring should be providing support for more IDEs.

Benoy Jose is a web developer with over six years of experience in J2EE and Microsoft technologies.
He is a Sun Certified programmer and enjoys writing technical and non-technical articles for various
magazines.

Vous aimerez peut-être aussi