java 동적 에이전트 실현 방법 분석

3961 단어 java동태대리
일부 자바 프로젝트에서는 mybatis와spring 통합에서 Mapper ScannerConfigurer의 사용이 있는데 이 클래스는 역방향 에이전트를 통해 인터페이스 기반의 동적 에이전트 클래스를 자동으로 생성합니다.
이를 감안하여 본고는 자바의 동적 에이전트를 간단히 분석하였다.
본고는 동적 프록시 시뮬레이션으로 업무를 처리하는 차단기를 사용합니다.
인터페이스:

public interface UserService {
  public void addUser();
  public void removeUser();
  public void searchUser();
}

구현 클래스:

public class UserServiceImpl implements UserService {
  public void addUser() {
    System.out.println("add user");
  }
  public void removeUser() {
    System.out.println("remove user");
  }
  public void searchUser() {
    System.out.println("search user");
  }
}

java 동적 에이전트의 실현은 두 가지 방식이 있다
1.jdk 자체 동적 에이전트
jdk 자체 동적 에이전트를 사용하려면 InvocationHandler 인터페이스와 Proxy 클래스를 알아야 합니다. 그들은 모두java에 있습니다.lang.reflect 싸주세요.
InvocationHandler 소개:
InvocationHandler는 프록시 인스턴스의 호출 프로세싱을 위한 인터페이스입니다.
각 프록시 인스턴스에는 연관된 InvocationHandler가 있습니다.프록시 호출 방법을 사용할 때, 이 방법은 InvocationHandler의 invoke 방법을 호출합니다.
Proxy 소개:
Proxy는 동적 프록시 클래스와 인스턴스를 만드는 정적 방법을 제공합니다.
인스턴스(AOP 트랜잭션 시뮬레이션):

public class TransactionInterceptor implements InvocationHandler {

  private Object target;

  public void setTarget(Object target) {
    this.target = target;
  }
  
  @Override
  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    System.out.println("start Transaction");
    method.invoke(target, args);
    System.out.println("end Transaction");
    return null;
  }

}

테스트 코드:

public class TestDynamicProxy {

  @Test
  public void testJDK() {
    TransactionInterceptor transactionInterceptor = new TransactionInterceptor();
    UserService userService = new UserServiceImpl();
    transactionInterceptor.setTarget(userService);
    UserService userServiceProxy =
        (UserService) Proxy.newProxyInstance(
            userService.getClass().getClassLoader(),
            userService.getClass().getInterfaces(),
            transactionInterceptor);
    userServiceProxy.addUser();
  }

}

테스트 결과:

start Transaction
add user
end Transaction

분명히, 우리는user Service Proxy라는 프록시 클래스를 통해 방법을 호출할 때, 방법 호출 전후에 업무의 시작과 종료를 진행한다.
2. 제3자 라이브러리 cglib
CGLIB는 기능이 강하고 고성능, 고품질의 코드 생성 라이브러리로 실행 기간에 자바 클래스를 확장하고 자바 인터페이스를 실현하는 데 사용된다.
JDK의 동적 에이전트와 가장 큰 차이점은 다음과 같습니다.
JDK 동적 에이전트는 인터페이스를 대상으로 하고 cglib는 클래스를 대상으로 에이전트를 실현한다. cglib의 원리는 지정된 목표 클래스에 대해 하위 클래스를 생성하고 그 중에서 덮어쓰는 방법으로 강화를 실현하지만 계승하기 때문에final 수식된 클래스에 대해 에이전트를 할 수 없다.
인스턴스 코드는 다음과 같습니다.

public class UserServiceCallBack implements MethodInterceptor {

  @Override
  public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
    System.out.println("start Transaction by cglib");
    methodProxy.invokeSuper(o, args);
    System.out.println("end Transaction by cglib");
    return null;
  }

}

테스트 코드:

public class TestDynamicProxy {

  @Test
  public void testCGLIB() {
    Enhancer enhancer = new Enhancer();
    enhancer.setSuperclass(UserServiceImpl.class);
    enhancer.setCallback(new UserServiceCallBack());
    UserServiceImpl proxy = (UserServiceImpl)enhancer.create();
    proxy.addUser();
  }

}

테스트 결과:

start Transaction by cglib
add user
end Transaction by cglib

흥미를 가진 독자들은 본고의 실례를 실제적으로 시험해 볼 수 있으니, 매우 큰 수확이 있을 것이라고 믿는다.

좋은 웹페이지 즐겨찾기