该工具只是对Guava中Retryer拙劣的模仿。意在学习其Java8使用方式,代码解耦精髓。
package com.fast.cattsoft.util; import java.util.concurrent.ExecutionException; public interface RetryResult{ boolean hasResult(); boolean hasException(); V getResult() throws IllegalAccessException; V get() throws ExecutionException; Throwable getException(); int getRetryCount(); }
package com.fast.cattsoft.util; public class SuccessRetryResultimplements RetryResult { private R result; private int tryCount; private long intervaTime; public SuccessRetryResult(R result, int tryCount, long intervaTime) { this.result = result; this.tryCount = tryCount; this.intervaTime = intervaTime; } @Override public boolean hasResult() { return true; } @Override public boolean hasException() { return false; } @Override public R getResult() { return result; } @Override public R get() { return result; } @Override public Throwable getException() { return null; } @Override public int getRetryCount() { return 0; } }
package com.fast.cattsoft.util; import java.util.concurrent.ExecutionException; public class ExceptionRetryResultimplements RetryResult { private ExecutionException e; private int tryCount; private long intervaTime; ExceptionRetryResult(ExecutionException e, int tryCount, long intervaTime) { this.e = e; this.tryCount = tryCount; this.intervaTime = intervaTime; } @Override public boolean hasResult() { return false; } @Override public boolean hasException() { return true; } @Override public R getResult() throws IllegalAccessException { throw new IllegalAccessException(""); } @Override public R get() throws ExecutionException { throw e; } @Override public Throwable getException() { return e.getCause(); } @Override public int getRetryCount() { return tryCount; } }
package com.fast.cattsoft.util; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.function.Predicate; public class RetryBuild{ private List >> predicates = new ArrayList >>(Collections.singleton(new Predicate >() { @Override public boolean test(RetryResult vRetryResult) { return false; } })); //重试次数 private int tryCount = 1; //每次重试失败后间隔时间 private long intervaTime = 1; public static RetryBuild newBuild() { return new RetryBuild (); } public RetryBuild buildTryCount(int tryCount) { this.tryCount = tryCount; return this; } public RetryBuild buildIntervaTime(long intervaTime) { this.intervaTime = intervaTime; return this; } public RetryBuild buildThrows(Class extends Throwable> throwables) { predicates.add(new ExceptionClassPredicate (throwables)); return this; } public RetryBuild buildResult(Predicate predicate) { predicates.add(new SuccessPredicate (predicate)); return this; } public Retry build() { return new Retry (tryCount, intervaTime, new OnPredicate (predicates)); } } class ExceptionClassPredicate implements Predicate > { private Class extends Throwable> exception; public ExceptionClassPredicate(Class extends Throwable> exception) { this.exception = exception; } @Override public boolean test(RetryResult vRetryResult) { if (!vRetryResult.hasException()) { return false; } return exception.isAssignableFrom(vRetryResult.getException().getClass()); } } class SuccessPredicate implements Predicate > { private Predicate delegate; public SuccessPredicate(Predicate predicate) { this.delegate = predicate; } @Override public boolean test(RetryResult vRetryResult) { if (!vRetryResult.hasResult()) { return false; } try { V result = vRetryResult.getResult(); boolean test = delegate.test(result); return test; } catch (Exception e) { throw new RuntimeException(""); } } } class ExceptionPredicate implements Predicate > { private Predicate delegate; public ExceptionPredicate(Predicate delegate) { this.delegate = delegate; } @Override public boolean test(RetryResult vRetryResult) { if (!vRetryResult.hasException()) { return false; } return delegate.test(vRetryResult.getException()); } } class OnPredicate implements Predicate > { //private List extends Predicate super V>> predicates; private List >> predicates; public OnPredicate(List >> predicates) { this.predicates = predicates; } @Override public boolean test(RetryResult vRetryResult) { for (int i = 0; i < predicates.size(); i++) { if (predicates.get(i).test(vRetryResult)) { return true; } } return false; } }
package com.fast.cattsoft.util; import com.github.rholder.retry.*; import org.springframework.util.CollectionUtils; import org.springframework.web.client.RestClientException; import java.util.*; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.function.Predicate; import java.util.function.Supplier; public class Retry{ //重试次数 private int tryCount = 1; //每次重试失败后间隔时间 private long intervaTime = 1; private Predicate > predicate; public Retry(int tryCount, long intervaTime, Predicate > predicate) { this.tryCount = tryCount; this.intervaTime = intervaTime; this.predicate = predicate; } public V call(Supplier supplier) throws ExecutionException { int currTryCount = 0; for (int i = 0; ; i++) { RetryResult retryResult; try { V result = supplier.get(); retryResult = new SuccessRetryResult(result, tryCount, intervaTime); } catch (Exception e) { retryResult = new ExceptionRetryResult(new ExecutionException(e), tryCount, intervaTime); } finally { currTryCount++; } if (!predicate.test(retryResult)) { return retryResult.get(); } if (currTryCount >= this.tryCount) { throw new RuntimeException("retry number more than " + this.tryCount); } else { try { Thread.sleep(this.intervaTime); } catch (InterruptedException e) { Thread.currentThread().interrupt(); throw new RuntimeException(""); } } } } public static void main(String[] args) throws Throwable { customReTry(); //guavaRetry(); } public static void customReTry() throws Throwable { Retry build = RetryBuild. newBuild() .buildTryCount(3) .buildIntervaTime(2000l) .buildResult(res -> { System.out.println("result has to than " + 6); return res > 6; }) .buildThrows(ArithmeticException.class) .build(); Integer call = build.call(() -> { int i = 0; //int b = 4 / i; return 5; }); System.out.println("result :" + call); } //可以参考guava重试代码 public static void guavaRetry() throws ExecutionException, RetryException { new ArrayList<>(1); Retryer build = RetryerBuilder. newBuilder() // .retryIfException(e -> e.getMessage().contains("")) .retryIfResult(e -> { System.out.println("result has to than 5"); return e > 5; }) .retryIfExceptionOfType(ArithmeticException.class) .withStopStrategy(StopStrategies.stopAfterAttempt(1)) .withWaitStrategy(WaitStrategies.fixedWait(3, TimeUnit.SECONDS)) .build(); Integer call = build.call(() -> { int i = 0; //int b = 4 / i; return 5; }); System.out.println("result :" + call); } }



