首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Spring-Retry:创建类似于@Retryable的自定义注释

Spring-Retry:创建类似于@Retryable的自定义注释
EN

Stack Overflow用户
提问于 2018-03-15 19:00:58
回答 2查看 1.4K关注 0票数 0

如果与数据库的连接失败,我有许多微服务需要重试机制。当发生SQLException和HibernateException时,必须触发此重试机制。在@Retryable中传递一个适当的拦截器将有效,但这必须包含在所有的微服务中。我们能否制作一个类似于@可还原的自定义注释,比如,它将在SQLException和HibernateException上触发重试。

这个注释的使用大致如下

代码语言:javascript
复制
@DatabaseRetryable
void executeQuery()
{
    //some code
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-03-15 21:34:39

这方面有几种方法:

  1. 使用spring项目并将其集成到您的应用程序中。但正如你所说的,这不是你想要的。这个框架提供的不仅仅是对异常的简单重试,而且比乍一看要广泛得多。
  2. 使用AOP (面向方面编程)模型和像AspectJ这样的库
  3. 创建一个自定义注释,在运行这些方法之前对类进行内省,看看它是否带有@CustomRetryable注释,然后运行retry方法。然而,这并不是很简单,需要与类进行适当的集成。这取决于您的应用程序是如何设计的,等等。
  4. 如果您想保持它尽可能简单:创建一个帮助类来为您执行重试。

我的建议是看看你的问题,你想要的解决方案不仅仅是这些重试吗?那就去图书馆吧。它是简单的一个/两个用例场景,然后采用实用类/方法方法。

这方面的一个非常粗略的例子可能是util类:

代码语言:javascript
复制
import java.util.logging.Level;
import java.util.logging.Logger;

public class RetryOperation {
    public static void main(String args[]) {
        retryOnException(() -> {throw new Exception();} , Exception.class, 4);
    }

    interface CustomSupplier<T> {
        T get() throws Exception;
    }
    static <E extends Exception, T> T retryOnException(CustomSupplier<T> method, Class<E> exceptionClass, int retries) {
        if (method == null) {
            throw new IllegalArgumentException("Method may not be null");
        }
        if (exceptionClass == null) {
            throw new IllegalArgumentException("Exception type needs to be provided");
        }
        int retryCount = 0;
        T result = null;

        while (retryCount < retries) {
            try {
                result = method.get();
            } catch (Exception exception) {
                if (exceptionClass.isAssignableFrom(exception.getClass()) && retryCount < retries) {
                    // log the exception here
                    retryCount++;
                    Logger.getLogger(RetryOperation.class.getName()).log(Level.INFO, String.format("Failed %d time to execute method retrying", retryCount));
                } else {
                    throw exception;
                }
            }
        }

        return result;
    }
}

请注意,这是一个粗略的例子,应该只使用函数来解释我在背后的想法。看看你到底需要什么,然后从那里设计。

票数 1
EN

Stack Overflow用户

发布于 2021-03-18 13:24:10

您可以通过创建一个具有所需名称的元注释来解决这个问题:

代码语言:javascript
复制
@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Retryable(
    value = { SQLException.class, HibernateException.class }
)
public @interface DatabaseRetryable {
}

您可以使用此元注释作为@Retryable的插入替代。同样的约束也适用--它只允许在一个地方配置一些常见的行为。您还可以使用它对所有相关服务使用相同的backOff

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49307334

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档