Java Dynamic Proxy 클래스는 두 가지 유형으로 나눌 수 있습니다.
정적 프록시 : 프로그래머가 생성하거나 특정 도구별로 소스 코드를 자동으로 생성하고 컴파일합니다. 프로그램이 실행되기 전에 프록시 클래스의 .class 파일이 이미 존재합니다.
동적 프록시 : 프로그램이 실행될 때 반사 메커니즘을 사용하여 동적으로 생성됩니다.
1. 첫째, 우리는 Java Dynamic Proxy를 시연 할 것입니다.
이제 우리는 다음과 같이 간단한 비즈니스 인터페이스를 가지고 있습니다.
코드 사본은 다음과 같습니다.
패키지 testaop;
{공개 인터페이스 {
공개 공허 SAYSHELLO (문자열 이름);
공개 무효 대화 (문자열 이름);
}
다음과 같이 간단한 구현 클래스
코드 사본은 다음과 같습니다.
패키지 testaop;
공개 수업은 {{
@보수
public void sayhello (문자열 이름) {
// TODO 자동 생성 메소드 스텁
System.out.println (이름 + ": 안녕하세요 여러분!");
}
@보수
공개 void talking (문자열 이름) {
// TODO 자동 생성 메소드 스텁
System.out.println (이름 + ": 조화로운 사회를 건설하기 위해 열심히 노력해야합니다!");
}
}
우리가 달성하고자하는 것은 말하기 전후에 처리를 동적으로 이식하고 이야기하는 것입니다.
JDK Dynamic Proxy는 주로 java.lang.reflect 패키지에서 두 개의 클래스를 사용합니다 : 프록시 및 호출 핸들러.
invocationHandler는이 인터페이스를 구현하여 크로스 절단 로직을 정의하고 반사 메커니즘을 통해 대상 클래스의 코드를 호출하는 인터페이스이며, 교차 절단 로직 및 비즈니스 로직을 동적으로 직조합니다.
Proxy는 invocationHandler를 사용하여 특정 인터페이스를 준수하고 대상 클래스의 프록시 객체를 생성하는 인스턴스를 동적으로 생성합니다.
다음과 같이 invocationHandler 인스턴스를 만듭니다.
코드 사본은 다음과 같습니다.
패키지 testaop;
import java.lang.reflect.invocationHandler;
import java.lang.reflect.method;
공개 클래스 MyInvocationHandler는 invocationHandler {
개인 객체 목표;
MyInvocationHandler (객체 대상) {
this.target = 대상;
}
@보수
공개 객체 호출 (객체 프록시, 메소드 메소드, 개체 [] args)
던질 수있는 {
// 대상 방법 전에 실행합니다
System.out.println ( " - - - - - - - - - - - - - - - - - - - - - - - - - -");
System.out.println ( "다음 사람에게 단계적으로 말하십시오!");
// 대상 메소드 호출
Object obj = method.invoke (target, args);
// 이후 대상 메소드를 실행합니다
System.out.println ( "모두 박수와 격려!");
반환 obj;
}
}
테스트는 다음과 같습니다.
코드 사본은 다음과 같습니다.
패키지 testaop;
java.lang.reflect.proxy import;
공개 클래스 JDKPROXYTEST {
public static void main (String [] args) {
// 대리인이 원하는 대상 비즈니스 카테고리
Target = New Sayimpl ();
// 대상 클래스와 크로스 컷 클래스를 함께 직조하십시오.
MyInvocationHandler handler = new MyInvocationHandler (Target);
// 프록시 인스턴스를 만듭니다
proxy = (say) proxy.newproxyinstance (
target.getClass (). getClassLoader (), // 대상 클래스의 클래스 로더
target.getClass (). getInterfaces (), // 대상 클래스의 인터페이스
핸들러); // 크로스 컷 클래스
Proxy.sayhello ( "Xiao Ming");
proxy.talking ( "Xiaoli");
}
}
작업은 다음과 같습니다.
코드 사본은 다음과 같습니다.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ---
다음 사람 무대에서 말 해주세요!
Xiao Ming : 안녕하세요 여러분!
모두가 박수를 보내고 격려했습니다!
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ---
다음 사람 무대에서 말 해주세요!
Xiaoli : 조화로운 사회를 건설하기 위해 열심히 노력해야합니다!
모두가 박수를 보내고 격려했습니다!
JDK Dynamic Proxy를 사용하는 데 큰 제한이 있습니다. 즉, 대상 클래스가 해당 메소드의 인터페이스를 구현해야하며 인터페이스에 대한 프록시 인스턴스 만 생성 할 수 있습니다. 위의 테스트 클래스에서 프록시 프록시의 NewProxyInstance 방법 에서이 방법의 두 번째 매개 변수는 대상 클래스의 인터페이스라는 것을 알 수 있습니다. 이 클래스가 인터페이스를 구현하지 않으면 CGLIB Dynamic Proxy에 따라 다릅니다.
CGLIB는 클래스에 대한 서브 클래스를 생성하고 서브 클래스에서 메소드 인터셉트 기술을 사용하여 모든 상위 클래스 메소드 호출을 가로 채고 상황에서 교차 절단 로직을 임플란트하는 매우 기본 바이트 코드 기술을 채택합니다.
2. 다음으로, 우리는 cglib 동적 프록시를 시연 할 것입니다.
우선, 우리는 내가 사용하는 패키지를 안내해야합니다.
먼저 프록시 제작자 cglibproxy를 만듭니다.
코드 사본은 다음과 같습니다.
패키지 testaop.cglib;
import java.lang.reflect.method;
import net.sf.cglib.proxy.enhancer;
import net.sf.cglib.proxy.methodinterceptor;
import net.sf.cglib.proxy.methodproxy;
공개 클래스 CGLIBPROXY는 MethodInterceptor {
Enhancer Enhancer = New Enhancer ();
공개 물체 getProxy (클래스 클라즈) {
// 생성 할 서브 클래스를 설정합니다
Enhance.setSuperClass (Clazz);
Enhancer.setCallback (this);
// 바이트 코드 기술을 통해 서브 클래스 인스턴스를 동적으로 만듭니다
return enhancer.create ();
}
@보수
공개 객체 인터셉트 (Object OBJ, 메소드 메소드, Object [] args,
MethodProxy Proxy) 던지기 가능 {
// TODO 자동 생성 메소드 스텁
System.out.println ( " - - - - - - - - - - - - - - - - - - - - - - - - - -");
System.out.println ( "다음 사람에게 단계적으로 말하십시오!");
// 대상 메소드 호출
객체 결과 = proxy.invokesuper (obj, args);
// 이후 대상 메소드를 실행합니다
System.out.println ( "모두 박수와 격려!");
반환 결과;
}
}
그런 다음 테스트 :
코드 사본은 다음과 같습니다.
패키지 testaop.cglib;
수입 testaop.saying;
가져 오기 testaop.sayingimpl;
공개 클래스 CGLIBPROXYTEST {
public static void main (String [] args) {
cglibproxy proxy = new cglibproxy ();
// 서브 클래스를 동적으로 생성하여 프록시 클래스를 만듭니다
Target = (say) proxy.getProxy (sayimpl.class);
Target.sayhello ( "Xiao Ming");
target.talking ( "Xiaoli");
}
}
결과는 JDK 동적 프록시와 다르지 않습니다.
JDK Dynamic Proxy와 CGLIB Dynamic Proxy는 모두 런타임 향상이며, 크로스 컷 코드를 프록시 클래스에 이식하여 향상시킵니다. 이와 달리, JDK 동적 프록시와 CGLIB 동적 프록시가 강화 될 때마다 강화 된 프로세싱을 통해 컴파일 기간에 크로스 컷 코드를 이식 할 수 있습니다.