일부 Java 프로젝트에서는 MapperScannerConfigurer가 mybatis와 spring의 통합에 사용됩니다. 이 클래스는 역방향 프록시를 통해 인터페이스 기반 동적 프록시 클래스를 자동으로 생성합니다.
이러한 관점에서 이 기사에서는 Java의 동적 프록시를 간략하게 분석합니다.
이 기사에서는 동적 프록시를 사용하여 트랜잭션을 처리하는 인터셉터를 시뮬레이션합니다.
인터페이스:
공개 인터페이스 UserService { 공개 무효 addUser(); 공개 무효 제거 사용자();}구현 클래스:
공용 클래스 UserServiceImpl은 UserService를 구현합니다. { public void addUser() { System.out.println("사용자 추가") } public void RemoveUser() { System.out.println("사용자 제거") } public void searchUser(); System.out.println("사용자 검색") }}Java 동적 프록시를 구현하는 방법에는 두 가지가 있습니다.
1. jdk와 함께 제공되는 동적 프록시
jdk와 함께 제공되는 동적 프록시를 사용하려면 InvocationHandler 인터페이스와 Proxy 클래스를 이해해야 합니다. 둘 다 java.lang.reflect 패키지에 있습니다.
InvocationHandler 소개:
InvocationHandler는 프록시 인스턴스의 호출 핸들러에 의해 구현되는 인터페이스입니다.
각 프록시 인스턴스에는 연결된 InvocationHandler가 있습니다. 프록시 인스턴스에서 메서드를 호출할 때 이 메서드는 InvocationHandler의 호출 메서드를 호출합니다.
프록시 소개:
프록시는 동적 프록시 클래스 및 인스턴스를 생성하기 위한 정적 메서드를 제공합니다.
예(AOP 트랜잭션 처리 시뮬레이션):
public class TransactionInterceptor는 InvocationHandler를 구현합니다. { private Object target; public void setTarget(Object target) { this.target = target; } @Override public Object Invoke(Object Proxy, Method method, Object[] args) Throwsable { System.out.println ("트랜잭션 시작"); method.invoke(target, args); System.out.println("트랜잭션 종료");테스트 코드:
공용 클래스 TestDynamicProxy { @Test 공용 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() }}테스트 결과:
트랜잭션 시작사용자 종료 트랜잭션 추가
분명히 userServiceProxy 프록시 클래스를 통해 메서드를 호출하면 메서드 호출 전후에 트랜잭션이 열리고 닫힙니다.
2. 타사 라이브러리 cglib
CGLIB는 Java 클래스를 확장하고 런타임 시 Java 인터페이스를 구현하기 위한 강력한 고성능, 고품질 코드 생성 라이브러리입니다.
JDK의 동적 프록시와 가장 큰 차이점은 다음과 같습니다.
JDK 동적 프록시는 인터페이스용이고 cglib는 클래스용 프록시를 구현합니다. cglib의 원칙은 지정된 대상 클래스에 대한 하위 클래스를 생성하고 메서드를 덮어쓰는 것입니다. 그러나 상속이 사용되므로 최종 클래스는 수정될 수 없습니다. 프록시됨.
예제 코드는 다음과 같습니다:
public class UserServiceCallBack은 MethodInterceptor를 구현합니다. { @Override public Object Intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { System.out.println("start Transaction by cglib"); ); System.out.println("cglib에 의한 트랜잭션 종료");테스트 코드:
public class TestDynamicProxy { @Test public void testCGLIB() { Enhancer Enhancer(); Enhancer.setSuperclass(UserServiceImpl.class); Enhancer.setCallback(new UserServiceImpl) Proxy = (UserServiceImpl)enhancer.create() ; 프록시.추가사용자() }}테스트 결과:
cglibadd userend에 의한 트랜잭션 시작 cglib에 의한 트랜잭션
관심 있는 독자들은 실제로 이 기사의 예제를 테스트해 볼 수 있으며, 나는 그들이 많은 것을 얻을 것이라고 믿습니다.