Professional Java Development with the Spring Framework
In contrast to traditional component frameworks such as EJB, Spring does not build remoting into the core component model. We strongly believe that business logic components should not be designed with remoting in mind. Instead, a typical Spring middle tier consists of local components with fine-grained interface methods and local invocation semantics, called by user interface controllers in the same process.
However, Spring does support remoting at the component level — not through the core container but through add-on support. If you need to expose a component to a remote process, you can define an exporter for that component, making it available through a specific remoting protocol. On the client side, a corresponding accessor can be defined to delegate method calls on a given interface to a specific remote service.
In keeping with Spring's overall philosophy, Spring's remoting support is designed to be as non-intrusive as possible. Neither service implementers nor callers need to be aware of remoting (at least not unnecessarily); exporters and accessors can be applied in a seamless fashion. Of course, the chosen interface needs to be suitable for remoting — that is, it needs to define coarse-grained methods with serializable arguments and return types. The interface used can still be a plain Java business interface, however: There is no need to derive from a base interface or throw a specific checked remoting exception.
You might choose to add a remote facade above a number of local components, to offer a coarser level of granularity to minimize chatty calling, improve performance, and observe the constraints relating to remote arguments and return types.
Thus Spring does not impose any constraints on remoting itself, and Spring's remoting support seamlessly fits into existing applications. For example, in the case of a web application that should be enriched with a remote service that exposes some existing functionality to cooperating applications, remoting can be added within the existing WAR deployment unit — using a lightweight, HTTP-based remoting protocol. There is no need to change the entire application architecture just because of the need to expose a remote service, which would be unavoidable when choosing to extend an existing web application with a remote EJB, for example.
Out of the box, the following remoting solutions are supported, sharing a common access and export style as much as possible:
-
Hessian: A slim binary protocol, based on HTTP. Language-independent but Java-oriented; currently mainly used for Java-to-Java remoting. Available under the Apache license from Caucho, the makers of the Resin application server.
-
Burlap: A slim XML-based protocol, based on HTTP. Like its sibling Hessian, it is language- independent but Java-oriented, and currently mainly used for Java-to-Java remoting. Available under the Apache license from Caucho.
-
HTTP invoker: Java serialization of remote invocations over HTTP. This is Spring's own take on HTTP-based Java-to-Java remoting, combining the strengths of HTTP-based remoting with the full power of Java serialization. Shares common infrastructure with RMI invoker (see the next bullet point).
-
RMI (traditional and invoker): Classic Java remoting infrastructure, using JRMP or IIOP as protocol (not HTTP-based). Can either be used with a traditional RMI service interface or with a plain Java business interface ("RMI invoker"). The latter shares common infrastructure with HTTP invoker.
-
WSDL/SOAP through JAX-RPC: For standard WSDL Web Services with SOAP over HTTP, handled through the standard Java API for Web Services. Can, for example, be used with Apache Axis. Completely language-independent, incurring extra effort for special types. Often used for communication with .NET applications.
Spring also provides support for accessing and implementing remote EJBs, sharing the access style with the lightweight remoting support. However, implementing a remote service as EJB does have some other implications, such as the introduction of a new deployment unit, with its own class loader, to be handled as a completely separate part of the application. Unless the remote services are the only entry points into the system, it is usually preferable to add a lightweight remoting strategy to the existing deployment unit, resulting in less complex overall architecture. See Chapter 11 for a discussion of Spring's EJB support.
Spring's remoting support focuses on stateless remoting, not keeping client-specific state on the server in between method invocations. This is usually the preferred strategy because it avoids the need for session state with timeouts and failover and is thus the most scalable option. If you need stateful remoting with client-specific sessions, consider the use of EJB's stateful session beans (which of course introduces a new deployment unit if your application did not use EJB before, as elaborated previously).
Throughout this chapter, we will show code and configuration examples from Spring's JPetStore sample application, which comes with the standard Spring distribution. JPetStore's web application exports its OrderService through all five different strategies presented in this chapter. A demo client in turn allows for fetching an order for a given ID, and performing the operation for each protocol. Have a look at JPetStore's readme file for deployment instructions. The sample application chapter of J2EE without EJB discusses the original Spring 1.0 JPetStore in detail.