所以我有一个生成的类 (PartnerConnection
),它向 SalesForce 云平台提供 DML 操作。由于与 SalesForce 或运行代码的系统的连接问题,我们遇到了长期运行的集成过程失败的问题。
为了解决这个问题,我用我命名的AdvancedPartnerConnection
扩展了PartnerConnection
类。 AdvancedPartnerConnection
只是覆盖 PartnerConnection
的方法并用try/catch/retry 逻辑包装它们。 p>
@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;
}
}
}
我已经为一些父类(super class)方法实现了这个,唯一的区别是被调用的方法及其参数。如果我决定更改任何重试逻辑,因为我希望它在所有方法中保持一致,这将成为一个真正的痛苦。
有没有人有办法将重试逻辑提取到单独的类或方法中,并可能传入函数调用?我在 .NET 中做过类似的事情,但我不确定如何在 Java 中完成。
最佳答案
您基本上想要捕获对所有对象方法的所有调用,并对所有这些方法应用一些逻辑。 你可以创建一个 Proxy并在 handler 中重试调用方法。
使用这种基于方法签名的方法,您可以决定要做什么。
另一种方法可以使用 AspectJ
或任何其他 AOP
框架,但您的用例添加这种依赖项非常简单,IMO。
如果您想添加一些behaviour
的类不是您的,那么这个解决方案可能不是最优雅的。但是,如果您愿意牺牲一些优雅来获得可维护性(因为您不是在复制代码),那么您可以:
class NotYourClass {
public void voidMethod() {}
public int intMethod(int n) { return 0; }
}
要创建一个代理
,您必须创建一个包含该类所有方法的接口(interface)
。这是糟糕的部分,但这不会对您的应用程序添加任何依赖性。
interface YourInterface {
public void voidMethod();
public int intMethod(int n);
}
接下来您需要一个包含行为
的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);
}
}
}
请记住,这是我的想法。但应该符合这些思路。
如果创建该接口(interface)对您来说是无法接受的,那么您可以查看一些AOP
框架。
关于java - 如何使此代码更干燥,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19737224/