Since its introduction with JDK 1.1, RMI has been a dominant protocol for
connecting Java application on both ends of the wire. However, RMI involves a
lot of boilerplate; for example, a remote interface must extend the
java.rmi.Remote interface, generate stubs and skeletons, complicated lookup,
handle RemoteException and MalformedUrlException, etc. So, you can well imagine
the complexity involved in using RMI for this job! Spring simplified the RMI
development experience by providing service exporters out of the box.
Furthermore, Spring provides a
seamless integration with HTTP protocol for exposing POJO components as remote
services, something that was not present earlier and one which has made
developers' life easy. In a series of two articles, we'll explore these two
popular techniques (RMI and HTTP), provided by the Spring framework and that
help expose POJOs as remote services.
Transparent remoting using RMI
In order to transparently expose POJOs as remote services, Spring provides
RmiServiceExporter to export Spring beans over the RMI protocol and
RmiProxyFactoryBean to consume
remote services. In this article, we'll expose a simple service as an RMI
service. To begin with, we'll write a service interface and an implementation
class, as shown below:
Direct Hit! |
Applies To: Adv Java developers USP: Export simple Spring beans as RMI services Primary Link: www.hibernate.org/hib_docs/reference/en/html/inheritance.html Keywords: Spring RMI |
package com.pcquest.remoting.service;
public interface rmservice
{
String getResult(String s);
}
As shown in the preceding code snippet, the service doesn't extend the
java.rmi.Remote interface and none of its methods throw java.rmi.Remote
Exception; this removes the boilerplate.
package com.pcquest.remoting.service;
public class rmserviceimpl implements rmservice
{
public rmserviceimpl(){
}
public String getResult(String a)
{
return "Hi "+a;
}
}
The service implementation class is simple. As opposed to traditional RMI
service implementation class, the rmserviceimpl POJO doesn't extend the
UnicastRemoteObject. However, you need to still wire the dependencies in the
Spring configuration file, as shown here:
value>com.pcquest.remoting.service.rmservice
The plumbing code is simple; as discussed before, the RmiService Exporter is
used to expose any Spring managed bean as an RMI service. The POJO bean is
wrapped inside an adapter class which implements the remote interface as
indicated by the 'service Interface.'
Furthermore, the RmiServiceExporter registers the same under the name
'MyService' and binds with port 1199. Notice that the remote service
implementation is injected into the 'service' property through Dependency
Injection (DI).
Consuming remote services
To consume a remote service, we'll use the Spring's RmiProxyFactoryBean. As
the name suggests, the RmiProxyFactoryBean is a factory bean that creates a
proxy to an RMI service. In our demo example we'll write a POJO which has a
dependency in the remote service (later, we'll wire this depencecy through
Spring DI), as shown here:
package com.pcquest.remoting.client;
import com.pcquest.remoting.
service.*;
public class SimpleObject {
private rmservice remoteService;
public void setRemoteService(rmservice remoteService) {
this.remoteService = remoteService;
}
...
Now, let's look at the Spring configuration file for plumbing all related
dependencies:
As shown, the URL of the RMI service is set through the serviceUrl property.
The serviceInterface property identifies the interface that the remote service
implements. The client will call business methods on the same interface.
Further, after the remote service is resolved, it's injected into the simple
object as discussed before.
Conclusion
Spring provides easy integration points for RMI protocol. However, RMI is Java
based remoting technique; both the client and the server must be written in
Java. Also, RMI uses arbitrary ports for communication; this could cause
problems working across firewalls. In the next part, we'll explore how Spring
supports HTTP remoting.