所以我有一个生成的类(PartnerConnection
),它为SalesForce云平台提供DML操作。由于与SalesForce或运行代码的系统的连接问题,我们遇到了长时间运行的集成过程失败的问题。
为了解决这个问题,我将PartnerConnection
类扩展为我所说的AdvancedPartnerConnection
。 AdvancedPartnerConnection
只是覆盖 PartnerConnection
的方法,并用 try / catch / retry 逻辑包装它们。
@Override
public QueryResult query(String queryString) throws ConnectionException{
int attempt = 0;
ConnectionException lastException = null;
while(true){
if(attempt < maxAttempts){ //maxAttempts constant
if(lastException != null){
try {
//exponentially increase wait times
Long sleepTime =(long) Math.pow(sleepBase, attempt) * 300;
Thread.sleep(sleepTime);
} catch (InterruptedException e1) {
// something bad has happen, throw the connection exception
throw lastException;
}
}
attempt ++;
try{
//call super class method
return super.query(queryString);
}catch(ConnectionException e){
lastException = e;
}
}else{
throw lastException;
}
}
}
我已经为少数超类方法实现了这个,唯一的区别是被调用的方法及其'参数。如果我决定更改任何重试逻辑,因为我希望它在所有方法中保持一致,这已经成为一种真正的痛苦。
有没有人有办法将重试逻辑提取到一个单独的类或方法中,并可能传入函数调用?我在.NET中做过这样的事情,但我不确定如何在java中做到这一点。
答案 0 :(得分:1)
您基本上希望捕获对所有对象方法的所有调用,并对所有对象方法应用一些逻辑。 您可以创建Proxy并在handler调用方法中重试。
使用基于方法签名的方法,您决定要做什么。
另一种方法可以使用AspectJ
或任何其他AOP
框架,但您的用例非常简单,可以添加这种依赖关系,IMO。
如果要添加某些behaviour
的类不是您的,那么此解决方案可能不是最优雅的。但是如果你愿意牺牲一些优雅来获得可维护性(因为你没有复制代码)那么你可以:
class NotYourClass {
public void voidMethod() {}
public int intMethod(int n) { return 0; }
}
要创建proxy
,您必须使用该类的所有方法创建interface
。这是一个糟糕的部分,但这不会为您的应用程序添加任何依赖。
interface YourInterface {
public void voidMethod();
public int intMethod(int n);
}
您需要的下一件事是InvocationHandler
,其中包含behavior
。
class YourInvocationHandler implements InvocationHandler {
private final NotYourClass target;
public YourInvocationHandler(NotYourClass target) {
this.target = target;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
try {
// Here you must look to the methods that are the ones that you want.
return method..invoke(target, args);
} catch (Exception e) {
// Retry?
method.invoke(target, args);
}
}
}
请记住,这是我的头脑。但应该是这样的。
如果创建该界面是您无法接受的,那么您可以查看一些AOP
框架。