|
|
|
|
Spring is a lightweight open source framework to develop enterprise applications using POJOs as building blocks and dependency injection. Dependency injection (DI) is a programming design pattern and architectural
model, sometimes also referred to as inversion of control or IOC, although
technically speaking, dependency injection specifically refers to an
implementation of a particular form of IOC. Dependancy Injection describes the
situation where one object uses a second object to provide a particular
capacity. For example, being passed a database connection as an argument to the
constructor instead of creating one internally. The term "Dependency injection"
is a misnomer, since it is not a dependency that is injected, rather it is a
provider of some capability or resource that is injected. There are three common
forms of dependency injection: setter-, constructor- and interface-based
injection. Dependency injection is a way to achieve loose coupling. Inversion of
control (IOC) relates to the way in which an object obtains references to its
dependencies. This is often done by a lookup method. The advantage of inversion
of control is that it decouples objects from specific lookup mechanisms and
implementations of the objects it depends on. As a result, more flexibility is
obtained for production applications as well as for testing. There are various IOC containers available currently. Apart from Spring, HiveMind, PicoContainer and avalon also supports IOC. The recent addition to this list is micro container from JBoss. Spring is most widely used framework and more and more enterprise applications previously written on EJBs are now being converted to Spring. One of the chief advantages of the Spring framework is its layered
architecture, which allows you to be selective about which of its components you
use while also providing a cohesive framework for J2EE application
development. The Spring modules are built on top of the core container, which
defines how beans are created, configured, and managed, as shown in the
following figure. Each of the modules (or components) that comprise the Spring
framework can stand on its own or be implemented jointly with one or more of the
others. The functionality of each component is as follows:
Spring framework functionality can be used in any J2EE server and most of it also is adaptable to non-managed environments. A central focus of Spring is to allow for reusable business and data-access objects that are not tied to specific J2EE services. Such objects can be reused across J2EE environments (Web or EJB), standalone applications, test environments, and so on, without any hassle. The core of Spring is the org.springframework.beans package, designed for working with JavaBeans. This package typically isn't used directly by users, but underpins much Spring functionality. 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. Bean factories support two modes of object:
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 container introduces 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. As org.springframework.beans.factory.BeanFactory is a simple interface, it can be implemented in different ways. The BeanDefinitionReader interface separates the metadata format from BeanFactory implementations themselves, so the generic BeanFactory implementations Spring provides can be used with different types of metadata. You could easily implement your own BeanFactory or BeanDefinitionReader, although few users find a need to. The most commonly used BeanFactory definitions are:
Each bean definition can be a POJO (defined by class name and JavaBean initialisation properties or constructor arguments), 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. BeanFactories can optionally participate in a hierarchy, "inheriting" definitions from their ancestors. This enables the sharing of common configuration across a whole application, while individual resources such as controller servlets also have their own independent set of objects. A Spring ApplicationContext is a subinterface of BeanFactory. 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. Beans defined in XML files are lazily loaded, which means that the beans themselves will not be instantiated until they are needed. 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 ServletContext or EJB. These hooks provided by the J2EE specification generally avoid the need to use a Singleton to bootstrap a bean factory. However, it's trivial to instantiate a BeanFactory programmatically if we wish. For example, we could create the bean factory and get a reference to the business object defined above in the following three lines of code: XmlBeanFactory bf = new XmlBeanFactory(new ClassPathResource("myFile.xml", getClass()));
MyBusinessObject mbo = (MyBusinessObject) bf.getBean("exampleBusinessObject");
This code will work outside an application server: it doesn't even depend on
J2EE, as the Spring IoC container is pure Java. Each bean definition can be a
POJO (defined by class name and JavaBean initialization properties) or a
FactoryBean. The FactoryBean interface adds a level of indirection to the
applications built using the Spring framework. You can download a sample spring 2.0 kickstart code from google code site http://code.google.com/p/spring-kickstart/ Spring AOP 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.) 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. Perhaps the commonest use of Spring AOP is for declarative transaction management. This builds on the transaction abstraction described above, and can deliver declarative transaction management on any POJO. Depending on the transaction strategy, the underlying mechanism can be JTA, JDBC, Hibernate or any other API offering transaction management. It's also possible to use Spring AOP to implement application-specific aspects. Whether or not you choose to do this depends on your level of comfort with AOP concepts, rather than Spring's capabilities, but it can be very useful. Application-specific aspects can be a powerful way of removing the need for boilerplate code across many methods. 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. The following XML snippet illustrates how to define an AOP proxy: <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 be interceptors or pointcuts (interceptors and information about when they 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. It's also possible to construct AOP proxies programmatically without using a BeanFactory, although this is more rarely used: TestBean target = new TestBean(); DebugInterceptor di = new DebugInterceptor(); MyInterceptor mi = new MyInterceptor(); ProxyFactory factory = new ProxyFactory(target); factory.addInterceptor(0, di); factory.addInterceptor(1, mi); // An "invoker interceptor" is automatically added to wrap the target ITestBean tb = (ITestBean) factory.getProxy(); Spring web flow in the latest version of Spring MVC web framework. Spring's documentation is a good place to start with: http://static.springframework.org/spring-webflow/docs/1.0.x/reference/index.html Struts could be integrated with Spring. Refer to this
sample chapter for the
nut and bolts required for integration. |
|
Send mail to
webmaster@mydeveloperconnection.com with questions or comments about this
web site. |