Using Spring's support for RMI, you can transparently expose your services through the RMI infrastructure. After having this set up, you basically have a configuration similar to remote EJBs, except for the fact that there is no standard support for security context propagation or remote transaction propagation. Spring does provide hooks for such additional invocation context when using the RMI invoker, so you can for example plug in security frameworks or custom security credentials here.
Using the RmiServiceExporter
, we can expose
the interface of our AccountService object as RMI object. The interface
can be accessed by using RmiProxyFactoryBean
, or
via plain RMI in case of a traditional RMI service. The
RmiServiceExporter
explicitly supports the
exposing of any non-RMI services via RMI invokers.
Of course, we first have to set up our service in the Spring container:
<bean id="accountService" class="example.AccountServiceImpl"> <!-- any additional properties, maybe a DAO? --> </bean>
Next we'll have to expose our service using the
RmiServiceExporter
:
<bean class="org.springframework.remoting.rmi.RmiServiceExporter"> <!-- does not necessarily have to be the same name as the bean to be exported --> <property name="serviceName" value="AccountService"/> <property name="service" ref="accountService"/> <property name="serviceInterface" value="example.AccountService"/> <!-- defaults to 1099 --> <property name="registryPort" value="1199"/> </bean>
As you can see, we're overriding the port for the RMI registry.
Often, your application server also maintains an RMI registry and it is
wise to not interfere with that one. Furthermore, the service name is
used to bind the service under. So right now, the service will be bound
at 'rmi://HOST:1199/AccountService'
. We'll use the
URL later on to link in the service at the client side.
Note | |
---|---|
The |
Our client is a simple object using the
AccountService
to manage accounts:
public class SimpleObject { private AccountService accountService; public void setAccountService(AccountService accountService) { this.accountService = accountService; } // additional methods using the accountService }
To link in the service on the client, we'll create a separate Spring container, containing the simple object and the service linking configuration bits:
<bean class="example.SimpleObject"> <property name="accountService" ref="accountService"/> </bean> <bean id="accountService" class="org.springframework.remoting.rmi.RmiProxyFactoryBean"> <property name="serviceUrl" value="rmi://HOST:1199/AccountService"/> <property name="serviceInterface" value="example.AccountService"/> </bean>
That's all we need to do to support the remote account service on
the client. Spring will transparently create an invoker and remotely
enable the account service through the
RmiServiceExporter
. At the client we're linking
it in using the RmiProxyFactoryBean
.