InvocationHandler 를 이용한 Dynamic Proxy 구현 하기

대충 쓰는 블로그·2022년 1월 9일
0
post-custom-banner
  1. 트랜잭션이 필요한 메소드마다 트랜잭션 처리 코드가 중복돼서 나타나는 비효율적 코드에 활용이 가능 하다.
  2. InvocationHandler 인터페이스를 구현 하여 트랜잭션 부가기능을 부가 해 주는 TransactionHandler 를 작성 한다.
public class TransactionHandler implements InvocationHandler {
  private Object target;
  private PlatformTransactionManager platformTransactionManager;
  private String pattern;

  /*
  요청을 위임할 타깃을 DI로 제공 받도록 함.
  어떠한 타깃 오브젝트 에도 적용 할 수 있다.
   */
  public void setTarget(Object target) {
    this.target = target;
  }

  public void setPlatformTransactionManager(PlatformTransactionManager platformTransactionManager) {
    this.platformTransactionManager = platformTransactionManager;
  }

  /*
  모든 메소드에 적용되지 않도록 패턴을 DI 받는다.
  "get" 으로 주면 get으로 시작하는 모든 메소드에 트랜잭션 적용
   */
  public void setPattern(String pattern) {
    this.pattern = pattern;
  }

  @Override
  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    if (method.getName().startsWith(pattern)) { // 패턴에 맞는 메소드 인지 확인
      return invokeInTransaction(method, args); // 패턴과 일치하면 호출
    } else {
      return method.invoke(target, args); // 아니라면 부가기능 없이 호출
    }
  }

  private Object invokeInTransaction(Method method, Object[] args) throws Throwable {
    TransactionStatus status = this.platformTransactionManager.getTransaction(new DefaultTransactionDefinition());
    try {
      Object ret = method.invoke(target, args);
      this.platformTransactionManager.commit(status);
      return ret;
    } catch (InvocationTargetException e) {
      this.platformTransactionManager.rollback(status);
      throw e.getTargetException();
    }
  }
}
profile
일단 대충 쓰고 나중에 수습 하던지 말던지
post-custom-banner

0개의 댓글