org.springframework.remoting.rmi
Class RmiClientInterceptor

java.lang.Object
  extended byorg.springframework.remoting.support.RemoteAccessor
      extended byorg.springframework.remoting.support.UrlBasedRemoteAccessor
          extended byorg.springframework.remoting.support.RemoteInvocationBasedAccessor
              extended byorg.springframework.remoting.rmi.RmiClientInterceptor
All Implemented Interfaces:
org.aopalliance.aop.Advice, InitializingBean, org.aopalliance.intercept.Interceptor, org.aopalliance.intercept.MethodInterceptor
Direct Known Subclasses:
RmiProxyFactoryBean

public class RmiClientInterceptor
extends RemoteInvocationBasedAccessor
implements org.aopalliance.intercept.MethodInterceptor, InitializingBean

Interceptor for accessing conventional RMI services or RMI invokers. The service URL must be a valid RMI URL like "rmi://localhost:1099/myservice".

RMI invokers work at the RmiInvocationHandler level, needing only one stub for any service. Service interfaces do not have to extend java.rmi.Remote or throw RemoteException; Spring's unchecked RemoteAccessException will be thrown on remote invocation failure. Of course, in and out parameters have to be serializable.

With conventional RMI services, this invoker is typically used with the RMI service interface. Alternatively, this invoker can also proxy a remote RMI service with a matching non-RMI business interface, i.e. an interface that mirrors the RMI service methods but does not declare RemoteExceptions. In the latter case, RemoteExceptions thrown by the RMI stub will automatically get converted to Spring's unchecked RemoteAccessException.

Since:
29.09.2003
Author:
Juergen Hoeller
See Also:
RmiServiceExporter, RmiProxyFactoryBean, RmiInvocationHandler, RemoteAccessException, RemoteException, Remote

Field Summary
 
Fields inherited from class org.springframework.remoting.support.RemoteAccessor
logger
 
Constructor Summary
RmiClientInterceptor()
           
 
Method Summary
 void afterPropertiesSet()
          Fetches RMI stub on startup, if necessary.
protected  java.lang.Object doInvoke(org.aopalliance.intercept.MethodInvocation invocation, java.rmi.Remote stub)
          Perform the given invocation on the given RMI stub.
protected  java.lang.Object doInvoke(org.aopalliance.intercept.MethodInvocation methodInvocation, RmiInvocationHandler invocationHandler)
          Apply the given AOP method invocation to the given RmiInvocationHandler.
protected  java.rmi.Remote getStub()
          Return the RMI stub to use.
 java.lang.Object invoke(org.aopalliance.intercept.MethodInvocation invocation)
          Fetches an RMI stub and delegates to doInvoke.
protected  java.rmi.Remote lookupStub()
          Create the RMI stub, typically by looking it up.
protected  java.lang.Object refreshAndRetry(org.aopalliance.intercept.MethodInvocation invocation)
          Refresh the RMI stub and retry the given invocation.
 void setCacheStub(boolean cacheStub)
          Set whether to cache the RMI stub once it has been located.
 void setLookupStubOnStartup(boolean lookupStubOnStartup)
          Set whether to look up the RMI stub on startup.
 void setRefreshStubOnConnectFailure(boolean refreshStubOnConnectFailure)
          Set whether to refresh the RMI stub on connect failure.
 
Methods inherited from class org.springframework.remoting.support.RemoteInvocationBasedAccessor
createRemoteInvocation, getRemoteInvocationFactory, setRemoteInvocationFactory
 
Methods inherited from class org.springframework.remoting.support.UrlBasedRemoteAccessor
getServiceUrl, setServiceUrl
 
Methods inherited from class org.springframework.remoting.support.RemoteAccessor
getServiceInterface, setServiceInterface
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

RmiClientInterceptor

public RmiClientInterceptor()
Method Detail

setLookupStubOnStartup

public void setLookupStubOnStartup(boolean lookupStubOnStartup)
Set whether to look up the RMI stub on startup. Default is true.

Can be turned off to allow for late start of the RMI server. In this case, the RMI stub will be fetched on first access.

See Also:
setCacheStub(boolean)

setCacheStub

public void setCacheStub(boolean cacheStub)
Set whether to cache the RMI stub once it has been located. Default is true.

Can be turned off to allow for hot restart of the RMI server. In this case, the RMI stub will be fetched for each invocation.

See Also:
setLookupStubOnStartup(boolean)

setRefreshStubOnConnectFailure

public void setRefreshStubOnConnectFailure(boolean refreshStubOnConnectFailure)
Set whether to refresh the RMI stub on connect failure. Default is false.

Can be turned on to allow for hot restart of the RMI server. If a cached RMI stub throws a ConnectException, a fresh proxy will be fetched and the invocation will be retried.

See Also:
ConnectException

afterPropertiesSet

public void afterPropertiesSet()
                        throws java.lang.Exception
Fetches RMI stub on startup, if necessary.

Specified by:
afterPropertiesSet in interface InitializingBean
Throws:
java.lang.Exception - in the event of misconfiguration (such as failure to set an essential property) or if initialization fails.
See Also:
setLookupStubOnStartup(boolean), lookupStub()

lookupStub

protected java.rmi.Remote lookupStub()
                              throws java.lang.Exception
Create the RMI stub, typically by looking it up. Called on interceptor initialization if cacheStub is true; else called for each invocation by getStub().

Default implementation looks up the service URL via java.rmi.Naming. Can be overridden in subclasses.

Returns:
the RMI stub to store in this interceptor
Throws:
java.lang.Exception - if proxy creation failed
See Also:
setCacheStub(boolean), getStub(), Naming.lookup(java.lang.String)

getStub

protected java.rmi.Remote getStub()
                           throws java.lang.Exception
Return the RMI stub to use. Called for each invocation.

Default implementation returns the proxy created on initialization, if any; else, it invokes lookupStub to get a new proxy for each invocation.

Can be overridden in subclasses, for example to cache a proxy for a given amount of time before recreating it, or to test the proxy whether it is still alive.

Returns:
the RMI stub to use for an invocation
Throws:
java.lang.Exception - if proxy creation failed
See Also:
lookupStub()

invoke

public java.lang.Object invoke(org.aopalliance.intercept.MethodInvocation invocation)
                        throws java.lang.Throwable
Fetches an RMI stub and delegates to doInvoke. If configured to refresh on connect failure, it will call refreshAndRetry on ConnectException.

Specified by:
invoke in interface org.aopalliance.intercept.MethodInterceptor
Throws:
java.lang.Throwable
See Also:
getStub(), doInvoke(MethodInvocation, Remote), refreshAndRetry(org.aopalliance.intercept.MethodInvocation), ConnectException

refreshAndRetry

protected java.lang.Object refreshAndRetry(org.aopalliance.intercept.MethodInvocation invocation)
                                    throws java.lang.Throwable
Refresh the RMI stub and retry the given invocation. Called by invoke on connect failure.

Parameters:
invocation - the AOP method invocation
Returns:
the invocation result, if any
Throws:
java.lang.Throwable - in case of invocation failure
See Also:
invoke(org.aopalliance.intercept.MethodInvocation)

doInvoke

protected java.lang.Object doInvoke(org.aopalliance.intercept.MethodInvocation invocation,
                                    java.rmi.Remote stub)
                             throws java.lang.Throwable
Perform the given invocation on the given RMI stub.

Parameters:
invocation - the AOP method invocation
stub - the RMI stub to invoke
Returns:
the invocation result, if any
Throws:
java.lang.Throwable - in case of invocation failure

doInvoke

protected java.lang.Object doInvoke(org.aopalliance.intercept.MethodInvocation methodInvocation,
                                    RmiInvocationHandler invocationHandler)
                             throws java.rmi.RemoteException,
                                    java.lang.NoSuchMethodException,
                                    java.lang.IllegalAccessException,
                                    java.lang.reflect.InvocationTargetException
Apply the given AOP method invocation to the given RmiInvocationHandler. The default implementation calls invoke with a plain RemoteInvocation.

Can be overridden in subclasses to provide custom RemoteInvocation subclasses, containing additional invocation parameters like user credentials. Can also process the returned result object.

Parameters:
methodInvocation - the current AOP method invocation
invocationHandler - the RmiInvocationHandler to apply the invocation to
Returns:
the invocation result
Throws:
java.lang.NoSuchMethodException - if the method name could not be resolved
java.lang.IllegalAccessException - if the method could not be accessed
java.lang.reflect.InvocationTargetException - if the method invocation resulted in an exception
java.rmi.RemoteException
See Also:
RemoteInvocation


Copyright (C) 2003-2004 The Spring Framework Project.