All of Spring's remoting support — including the support for remote EJBs — shares a common access style, which essentially consists of two parts:
Proxy factory: To "import" a remote service into a client-side Spring context, a special factory bean for a specific protocol is defined. Configuration such as the service interface to use and the URL of the target service is defined on the factory bean, which in turn exposes a proxy that implements the specified service interface.
Proxy behavior: A proxy for a remote service delegates each method invocation on the proxy to the remote service. Any exception thrown by the target service will be propagated through the proxy. If the remote invocation itself failed, a proxy will consistently throw Spring's generic RemoteAccessException — no matter which remoting solution is used under the hood.
Spring's org.springframework.remoting.RemoteAccessException is a generic, unchecked exception that indicates a remote invocation failure. It does not have to be declared on the service interface because of its unchecked nature. Nevertheless, it can be caught and handled in a consistent fashion by the client — or simply let through if considered fatal.
Spring's remoting support is mainly designed for plain Java business interfaces, not declaring any remoting exception. Handling remote invocation failures through throwing the unchecked RemoteAccessException will be managed by the protocol-specific proxies and won't affect the service implementation on the server side at all. This model is seamless with Hessian, Burlap, and HTTP invoker, which have all been designed for plain Java interfaces in the first place.
With Spring's RMI support, either traditional RMI service interfaces or plain Java business interfaces can be used. In the former case, the service interfaces will derive from java.rmi.Remote and throwjava.rmi.RemoteException, as required for traditional RMI interfaces; of course, the client will need to handle the checked RemoteException accordingly in such a scenario. In the latter case, the RMI infrastructure will be used for tunneling invocations on plain Java interfaces — the RMI invoker mode.
A further option with Spring's RMI, JAX-RPC, and EJB support is to specify a plain Java business interface for the proxy, despite the target service using a traditional RMI service interface. In that case, each invocation on the proxy will be converted into a corresponding invocation on the underlying RMI stub for the remote service; checked RMI RemoteExceptions thrown will automatically get converted to Spring's unchecked RemoteAccessException. Of course, the target service still implements the RMI service interface, without having to implement the Java business interface used by the client — in contrast to when using RMI invoker, where both the client and the server use the same plain Java business interface.
We will show examples for various service interface scenarios in the corresponding sections for each remoting solution.
On the server side, Spring also provides a common style for exporting a service: defining an exporter for an existing Spring-managed bean, exposing it as remote service at a specific URL. The configuration is virtually the same for Hessian, Burlap, and HTTP invoker. The RMI support does not have to run in a servlet container, but is analogous in all other respects. Web Services are usually exported in a tool-specific style; standard JAX-RPC unfortunately does not allow for seamless exporting of an existing service instance.
Spring provides a common configuration style for all supported remoting solutions — as common as possible — both for client-side accessors and server-side exporters.
On the client side, plain Java business interfaces can be used for accessing a remote service with a common proxy definition style. All remoting proxies will throw Spring's unchecked RemoteAccessException in a consistent fashion on a remote invocation failure.
On the server side, Spring allows for exporting an existing Spring-managed bean as remote service, under a specific protocol. This is particularly seamless for Hessian, Burlap, and HTTP invoker, but also for RMI when leveraging Spring's RMI invoker mechanism. The same service instance can be exported under multiple protocols at the same time, at different URLs.
This consistency means that once you understand Spring's approach to remoting, you will find it easy to work with whatever remoting protocol is best suited to a particular requirement.