public class RmiClientInterceptor extends RemoteInvocationBasedAccessor implements MethodInterceptor
MethodInterceptor
for accessing conventional
RMI services or RMI invokers. The service URL must be a valid RMI URL
(e.g. "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 java.rmi.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.
RmiServiceExporter
,
RmiProxyFactoryBean
,
RmiInvocationHandler
,
RemoteAccessException
,
RemoteException
,
Remote
logger
Constructor and Description |
---|
RmiClientInterceptor() |
Modifier and Type | Method and Description |
---|---|
void |
afterPropertiesSet()
Invoked by the containing
BeanFactory after it has set all bean properties
and satisfied BeanFactoryAware , ApplicationContextAware etc. |
protected java.lang.Object |
doInvoke(MethodInvocation invocation,
java.rmi.Remote stub)
Perform the given invocation on the given RMI stub.
|
protected java.lang.Object |
doInvoke(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(MethodInvocation invocation)
Fetches an RMI stub and delegates to
doInvoke . |
protected boolean |
isConnectFailure(java.rmi.RemoteException ex)
Determine whether the given RMI exception indicates a connect failure.
|
protected java.rmi.Remote |
lookupStub()
Create the RMI stub, typically by looking it up.
|
void |
prepare()
Fetches RMI stub on startup, if necessary.
|
protected java.lang.Object |
refreshAndRetry(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.
|
void |
setRegistryClientSocketFactory(java.rmi.server.RMIClientSocketFactory registryClientSocketFactory)
Set a custom RMI client socket factory to use for accessing the RMI registry.
|
createRemoteInvocation, getRemoteInvocationFactory, recreateRemoteInvocationResult, setRemoteInvocationFactory
getServiceUrl, setServiceUrl
getServiceInterface, setServiceInterface
getBeanClassLoader, overrideThreadContextClassLoader, resetThreadContextClassLoader, setBeanClassLoader
public void setLookupStubOnStartup(boolean lookupStubOnStartup)
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.
setCacheStub(boolean)
public void setCacheStub(boolean cacheStub)
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.
setLookupStubOnStartup(boolean)
public void setRefreshStubOnConnectFailure(boolean refreshStubOnConnectFailure)
Can be turned on to allow for hot restart of the RMI server. If a cached RMI stub throws an RMI exception that indicates a remote connect failure, a fresh proxy will be fetched and the invocation will be retried.
ConnectException
,
ConnectIOException
,
NoSuchObjectException
public void setRegistryClientSocketFactory(java.rmi.server.RMIClientSocketFactory registryClientSocketFactory)
RMIClientSocketFactory
,
LocateRegistry.getRegistry(String, int, RMIClientSocketFactory)
public void afterPropertiesSet()
InitializingBean
BeanFactory
after it has set all bean properties
and satisfied BeanFactoryAware
, ApplicationContextAware
etc.
This method allows the bean instance to perform validation of its overall configuration and final initialization when all bean properties have been set.
afterPropertiesSet
in interface InitializingBean
afterPropertiesSet
in class UrlBasedRemoteAccessor
public void prepare() throws RemoteLookupFailureException
RemoteLookupFailureException
- if RMI stub creation failedsetLookupStubOnStartup(boolean)
,
lookupStub()
protected java.rmi.Remote lookupStub() throws RemoteLookupFailureException
Called on interceptor initialization if "cacheStub" is "true";
else called for each invocation by getStub()
.
The default implementation looks up the service URL via
java.rmi.Naming
. This can be overridden in subclasses.
RemoteLookupFailureException
- if RMI stub creation failedsetCacheStub(boolean)
,
Naming.lookup(java.lang.String)
protected java.rmi.Remote getStub() throws RemoteLookupFailureException
The default implementation returns the stub created on initialization,
if any. Else, it invokes lookupStub()
to get a new stub for
each invocation. This can be overridden in subclasses, for example in
order to cache a stub for a given amount of time before recreating it,
or to test the stub whether it is still alive.
RemoteLookupFailureException
- if RMI stub creation failedlookupStub()
public java.lang.Object invoke(MethodInvocation invocation) throws java.lang.Throwable
doInvoke
.
If configured to refresh on connect failure, it will call
refreshAndRetry(org.aopalliance.intercept.MethodInvocation)
on corresponding RMI exceptions.invoke
in interface MethodInterceptor
invocation
- the method invocation joinpointJoinpoint.proceed()
;
might be intercepted by the interceptorjava.lang.Throwable
- if the interceptors or the target object
throws an exceptiongetStub()
,
doInvoke(MethodInvocation, Remote)
,
refreshAndRetry(org.aopalliance.intercept.MethodInvocation)
,
ConnectException
,
ConnectIOException
,
NoSuchObjectException
protected boolean isConnectFailure(java.rmi.RemoteException ex)
The default implementation delegates to
RmiClientInterceptorUtils.isConnectFailure(java.rmi.RemoteException)
.
ex
- the RMI exception to check@Nullable protected java.lang.Object refreshAndRetry(MethodInvocation invocation) throws java.lang.Throwable
invocation
- the AOP method invocationjava.lang.Throwable
- in case of invocation failureinvoke(org.aopalliance.intercept.MethodInvocation)
@Nullable protected java.lang.Object doInvoke(MethodInvocation invocation, java.rmi.Remote stub) throws java.lang.Throwable
invocation
- the AOP method invocationstub
- the RMI stub to invokejava.lang.Throwable
- in case of invocation failure@Nullable protected java.lang.Object doInvoke(MethodInvocation methodInvocation, RmiInvocationHandler invocationHandler) throws java.rmi.RemoteException, java.lang.NoSuchMethodException, java.lang.IllegalAccessException, java.lang.reflect.InvocationTargetException
RmiInvocationHandler
.
The default implementation delegates to RemoteInvocationBasedAccessor.createRemoteInvocation(org.aopalliance.intercept.MethodInvocation)
.
methodInvocation
- the current AOP method invocationinvocationHandler
- the RmiInvocationHandler to apply the invocation tojava.rmi.RemoteException
- in case of communication errorsjava.lang.NoSuchMethodException
- if the method name could not be resolvedjava.lang.IllegalAccessException
- if the method could not be accessedjava.lang.reflect.InvocationTargetException
- if the method invocation resulted in an exceptionRemoteInvocation