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] 为上层方法栈,通过上层方法的栈帧得到上层方法的方法名和类名。

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

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

  • 相关阅读:
    Session、Cookie、Application、ViewState和Cache 这四者的区别
    用C#构造HighChart类库,把数据转换成JSON第二阶段完成50%API,已经能满足项目要求了
    HttpHandler 在SharePoint 2010中的应用
    SharePoint 2010 在多台前端环境 还原 网站集 问题解析
    SharePoint 2010 PowerShell 系列 之 文档管理 高级应用和企业案例(文档迁移)
    设计模式策略模式
    CentOS7 安装Hbase集群
    CentOS7 安装zookeeper
    CentOS7 安装Hadoop集群环境
    Django Rest Framework关闭CSRF验证
  • 原文地址:https://www.cnblogs.com/knightsu/p/9504058.html
Copyright © 2011-2022 走看看