Spring Retry 실현 원리 상세 설명

4434 단어 SpringRetry
앞의 이 블 로그에서 Spring Retry 의 사용 을 소개 했다.본 고 는 간단 한 예 를 통 해 Spring Retry 의 실현 원 리 를 보 여 주 었 다.예 에서 정 의 된 주 해 는 재 시도 횟수 속성 만 포함 하고 실제 Spring Retry 에서 주 해 는 속성 을 설정 할 수 있 는 것 이 많 으 며 단순히 원 리 를 설명 하기 위해 간단하게 스프링 Retry 에 대해 관련 문서,블 로 그 를 조회 할 수 있다.
주해 정의

package retry.annotation;

import java.lang.annotation.*;

/**
 * Created by Jack.wu on 2016/9/30.
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Retryable {

  int maxAttemps() default 0;

}
대리 실현
Cglib 를 대리 도구 로 하여 먼저 Callback 실현 을 쓰 는 것 도 재 시도 실현 의 핵심 논리 이다.

package retry.interceptor;

import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import retry.annotation.Retryable;

import java.lang.reflect.Method;

/**
 * Created by Jack.wu on 2016/9/30.
 */
public class AnnotationAwareRetryOperationsInterceptor implements MethodInterceptor{

  //      
  private int times = 0;

  @Override
  public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
    //         Retryable  
    Retryable retryable = method.getAnnotation(Retryable.class);
    if(retryable == null){
      return proxy.invokeSuper(obj,args);
    }else{ // Retryable  ,        
      int maxAttemps = retryable.maxAttemps();
      try {
        return proxy.invokeSuper(obj,args);
      } catch (Throwable e) {
        if(times++ == maxAttemps){
          System.out.println("        :" + maxAttemps + ",    !");
        }else{
          System.out.println("  " + method.getName() + "    ,   " + times +"   。。。");
          //      invokeSuper  ,invokeSuper     interceptor   
          proxy.invoke(obj,args);
        }
      }
    }
    return null;
  }
}

그 다음 에 프 록 시 클래스 를 쓰 고 AnnotationAware Retry Operations Interceptor 를 차단기 로 사용 합 니 다.

package retry.core;
import net.sf.cglib.proxy.Enhancer;
import retry.interceptor.AnnotationAwareRetryOperationsInterceptor;

/**
 * Created by Jack.wu on 2016/9/30.
 */
public class SpringRetryProxy {

  public Object newProxyInstance(Object target){
    Enhancer enhancer = new Enhancer();
    enhancer.setSuperclass(target.getClass());
    enhancer.setCallback(new AnnotationAwareRetryOperationsInterceptor());
    return enhancer.create();
  }
}
 테스트
사용자 관련 업무 방법 을 통 해 위의 코드 를 테스트 합 니 다.
인터페이스 정의:

package facade;

/**
 * Created by Jack.wu on 2016/9/26.
 */
public interface UserFacade {

  void add() throws Exception;

  void query() throws Exception;
}

인터페이스 구현:package facade.impl;

import facade.UserFacade;
import retry.annotation.Retryable;
/**
 * Created by Jack.wu on 2016/9/26.
 */
public class UserFacadeImpl implements UserFacade {
  @Override
  public void add() throws Exception {
    System.out.println("    。。。");
    throw new RuntimeException();
  }

  @Override
  @Retryable(maxAttemps = 3)
  public void query() {
    System.out.println("    。。。");
    throw new RuntimeException();
  }
}
테스트:

public class Main {

  public static void main(String[] args) throws Exception{
    UserFacadeImpl user = new UserFacadeImpl();
    //SpringRetry    
    SpringRetryProxy springRetryProxy = new SpringRetryProxy();
    UserFacade u = (UserFacade)springRetryProxy.newProxyInstance(user);
    //u.add();//     
    u.query();//    
  }
}

add 방법 은 재 시도 주 해 를 추가 하지 않 습 니 다.프로그램 이 이상 하 게 끝 났 습 니 다.query 방법 은 재 시도 주 해 를 추가 하고 재 시도 3 회 설정 합 니 다.실행 효 과 는 다음 과 같 습 니 다.

이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

좋은 웹페이지 즐겨찾기