• java反射实现接口重试


    工具类:

    import java.lang.reflect.Method;

    public class RetryUtil {
    private static ThreadLocal<Integer> retryTimesInThread = new ThreadLocal<>();

    /**
    * 设置当前方法重试次数
    *
    * @param retryTimes
    * @return
    */
    public static RetryUtil setRetryTimes(Integer retryTimes) {
    if (retryTimesInThread.get() == null)
    retryTimesInThread.set(retryTimes);
    return new RetryUtil();
    }

    /**
    * 重试当前方法
    * <p>按顺序传入调用者方法的所有参数</p>
    * @param args
    * @return
    */
    public Object retry(Object... args) {
    try {
    Integer retryTimes = retryTimesInThread.get();
    if (retryTimes <= 0) {
    retryTimesInThread.remove();
    return null;
    }
    retryTimesInThread.set(--retryTimes);
    String upperClassName = Thread.currentThread().getStackTrace()[2].getClassName();
    String upperMethodName = Thread.currentThread().getStackTrace()[2].getMethodName();

    Class clazz = Class.forName(upperClassName);
    Object targetObject = clazz.newInstance();
    Method targetMethod = null;
    for (Method method : clazz.getDeclaredMethods()) {
    if (method.getName().equals(upperMethodName)) {
    targetMethod = method;
    break;
    }
    }
    if (targetMethod == null)
    return null;
    targetMethod.setAccessible(true);
    return targetMethod.invoke(targetObject, args);
    } catch (Exception e) {
    e.printStackTrace();
    return null;
    }
    }
    }
    调用:
    RetryUtil.setRetryTimes(3).retry(url, workOrderPost);

    为了防止多线程情况下出现并发问题,这里定义了一个 ThreadLocal 变量来存储当前线程的重试次数。然后通过 setRetryTimes ,一个静态方法来设置这个重试次数,并返回一个 RetryUtil 对象。

    调用者通过返回的 RetryUtil 对象调用 retry 方法实现重试。retry 方法接收一个可变参数,因为调用者实际的参数不确定,这里要求按顺序传入调用者方法的所有参数。

    接下来判断 ThreadLocal 变量是否小于等于 0 ,如果是,则说明重复次数已达到,返回 null;如果不是,则让 ThreadLocal 变量减一。接下来:

    String upperClassName = Thread.currentThread().getStackTrace()[2].getClassName();
    String upperMethodName = Thread.currentThread().getStackTrace()[2].getMethodName();

    来获取当前方法(retry)的上层方法名和上层类名。Thread.currentThread().getStackTrace() 得到线程的方法栈数组,数组的第二个元素 Thread.currentThread().getStackTrace() [1]  为当前方法栈,第三个元素 Thread.currentThread().getStackTrace() [2] 为上层方法栈,通过上层方法的栈帧得到上层方法的方法名和类名。

    下面就是通过反射获取该类的所有方法,循环判断方法名是否等于所要重复执行的方法,如果是的话,执行该方法,参数就是传入可变参数。

    注意睡眠重试确保之前操作事务提交,避免超时。

  • 相关阅读:
    存储过程的设计规则
    企业管理器里删除不需要的注册
    SQL Server 大数据量插入和索引关系
    【2011520】无法使用主机名连接数据库
    SQL Server 查看存储过程
    SQL Server dbcc inputbuffer
    如何选择行版本的隔离级别
    ObjectiveC中Selector基本概念和操作
    Objectivec的@property 详解
    objectivec 关键字和概念
  • 原文地址:https://www.cnblogs.com/knightsu/p/9504058.html
Copyright © 2020-2023  润新知