package org.springframework.remoting.support;
import java.lang.reflect.InvocationTargetException;
import java.util.Iterator;
import java.util.List;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.remoting.support.RemoteAccessor;
/**
* Factory bean for proxies to redundant services. Behaves like the
proxied
* service when used as bean reference, exposing the specified service
* interface, but with transparent fail-over. All call to the proxy are
* delegated to the first object in the list of service providers (@see
* #setServiceProviders(List)). When this delegated call fails, the
next
* provider in the list will be called, etc.
*
* @author be324288
*
*/
public class FailoverProxyFactoryBean extends RemoteAccessor implements
MethodInterceptor,
InitializingBean, FactoryBean {
private Object serviceProxy;
private List serviceProviders;
/**
* The list of (redundant) objects that implement the interface
specified
* with {@link RemoteAccessor#setServiceInterface(java.lang.Class)}
*
* @return
*/
public List getServiceProviders() {
return serviceProviders;
}
/**
* @param serviceProviders
*/
public void setServiceProviders(List serviceProviders) {
this.serviceProviders = serviceProviders;
}
public void afterPropertiesSet() throws Exception {
if (getServiceInterface() == null) {
throw new IllegalArgumentException("serviceInterface is
required");
}
if (serviceProviders == null || serviceProviders.isEmpty()) {
throw new IllegalArgumentException("serviceBeans is
required");
}
for (Object o : serviceProviders) {
if (!getServiceInterface().isInstance(o)) {
throw new IllegalArgumentException(o.getClass()
+ " does not implement the serviceInterface: "
+
getServiceInterface());
}
}
this.serviceProxy =
ProxyFactory.getProxy(getServiceInterface(), this);
}
public Object getObject() {
return this.serviceProxy;
}
public Class getObjectType() {
return getServiceInterface();
}
public boolean isSingleton() {
return true;
}
public Object invoke(MethodInvocation mi) throws Throwable {
Iterator iter = serviceProviders.iterator();
while (iter.hasNext()) {
Object bean = iter.next();
try {
return
bean.getClass().getMethod(mi.getMethod().getName(),
(Class[])
mi.getMethod().getParameterTypes()).invoke(bean,
mi.getArguments());
} catch (InvocationTargetException e) {
// try next bean or throw exception if this is the last
bean
if (!iter.hasNext()) {
throw e.getCause();
}
}
}
return null;
}
}
No comments:
Post a Comment