zoukankan      html  css  js  c++  java
  • 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] 为上层方法栈,通过上层方法的栈帧得到上层方法的方法名和类名。

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

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

  • 相关阅读:
    磁盘分区,fdisk,gdisk,开机自动挂载,swap分区,修复文件系统,备份文件
    进程脱离窗口运行,僵尸、孤儿进程
    top命令、kill命令
    进程状态
    rpm包、挂载、yum命令
    DRF源码分析
    forms组件源码
    Django CBV源码分析
    魔法方法
    鸭子类型
  • 原文地址:https://www.cnblogs.com/knightsu/p/9504058.html
Copyright © 2011-2022 走看看