所以我有一个生成的类(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中做。
最佳答案
您基本上想要捕获对所有对象方法的所有调用,并对所有对象方法应用一些逻辑。
您可以创建Proxy并在handler调用方法中重试。
使用这种基于方法签名的方法,您可以决定要做什么。
另一种方法可以使用AspectJ
或任何其他AOP
框架,但是您的用例添加这种依赖关系非常简单,imo。
如果您要添加的类不是您的类,那么这个解决方案可能不是最优雅的。但是如果您愿意牺牲一些优雅来获得可维护性(因为您没有复制代码),那么您可以:
class NotYourClass {
public void voidMethod() {}
public int intMethod(int n) { return 0; }
}
要创建
behaviour
,必须使用类的所有方法创建proxy
。这是一个糟糕的部分,但这不会给应用程序添加任何依赖项。interface YourInterface {
public void voidMethod();
public int intMethod(int n);
}
接下来需要的是包含
interface
的InvocationHandler
。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);
}
}
}
请记住,这是从我的头顶开始的。但应该是这样的。
如果创建该接口对您来说是不可接受的,那么您可以查看一些
behavior
框架。