Java 디자인 모드 - 동적 프록시 모드
3556 단어 java 학습 노트
프록시 모드
프록시 모드의 의도는 인터페이스나 자리 차지 문자를 통해 대상에 대한 접근을 제어하는 것이다
대리 대상은 보통 실제 대상과 같은 인터페이스를 가지고 있으며, 제어 방문을 통해 요청을 합리적으로 밑바닥의 실제 대상에게 전달한다
동적 에이전트 (에이전트가 필요한 클래스가 인터페이스를 실현함)
반사 클래스 Proxy와 InvocationHandler 리셋 인터페이스를 통해
동적 에이전트는 에이전트 대상을 통해 실제 대상을 포장하고 에이전트 대상을 통해 실제 대상에 대한 요청을 차단한 다음에 에이전트로 실제 대상에게 전송하며 호출을 차단하기 전이나 이후에 자신의 코드를 추가할 수 있도록 한다
동적 에이전트 만들기
(1) 실제 대상이 실현하는 모든 인터페이스를 얻는다.obj가 실제 대상입니다.
Class[] classes=obj.getClass().getInterfaces();
(2) 실제 대상이 속한 클래스를 획득하는 클래스 캐리어
ClassLoader loader=obj.getClass().getClassLoader();
(3) 프록시 객체 작성 자체
이 대상 소속 클래스는java를 실현해야 합니다.lang.reflect 패키지의 InvocationHandler 커넥터입니다.이 인터페이스에서 invoke 방법을 정의했습니다
다음:InvocationHandler 인터페이스를 실현하여 invoke 방법을 다시 쓰고result=method.voke(obj,args) 이 줄은 반사를 통해 목표를 실제 대상에게 호출하여 전송하는 것이다. 전송 전후에 코드를 추가하고 간단한 로그 기능을 실현하면 프록시 클래스가 만들어진다.package xidian.lili.edu.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class ImpatientProxy implements InvocationHandler{
private Object obj;
public ImpatientProxy(Object obj){
this.obj=obj;
}
@Override
public Object invoke(Object obj, Method method, Object[] args) throws Throwable {
Object result;
long t1=System.currentTimeMillis();
result=method.invoke(obj, args);
long t2=System.currentTimeMillis();
System.out.println("It takes "+(t2-t1)+" millis to invoke "+method.getName());
return result;
}
}
그러면 프록시 클래스 ImpatientProxy의 대상을 사용하려면java를 사용해야 합니다.lang.reflect 패키지의 Proxy 클래스, 이 클래스는 하나의 인터페이스, 하나의 클래스 마운트와 Impatient Proxy 실례 대상이 필요하기 때문에 우리는 에이전트 클래스에 다음과 같은 방법을 추가할 수 있습니다. 이 newInstance의 정적 방법은 우리에게 정적 에이전트 대상을 만들어 줍니다. 이 방법이 되돌아오는 대상은 포장된 대상의 모든 인터페이스를 실현하고 임의의 유형의 대상으로 전환할 수 있습니다.package xidian.lili.edu.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ImpatientProxy implements InvocationHandler{
private Object obj;
public ImpatientProxy(Object obj){
this.obj=obj;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result;
long t1=System.currentTimeMillis();
result=method.invoke(obj, args);
long t2=System.currentTimeMillis();
System.out.println("It takes "+(t2-t1)+" millis to invoke "+method.getName());
return result;
}
public static Object newInstance(Object obj){
ClassLoader loader=obj.getClass().getClassLoader();
Class[] classes=obj.getClass().getInterfaces();
return Proxy.newProxyInstance(loader, classes, new ImpatientProxy(obj));
}
}
동적 에이전트를 썼을 때, 예를 들어, 대상이 차단하고 싶은 방법에 속하는 인터페이스를 실현하면, 에이전트를 사용하여 대상을 포장할 수 있다.package xidian.lili.edu.proxy;
import java.util.HashSet;
import java.util.Set;
public class ShowDynamicProxy {
public static void main(String[] args) {
Set s=new HashSet();
// s
s=(Set) ImpatientProxy.newInstance(s);
s.add("hello world");
s.isEmpty();
}
}
방법의 실행 전후에 호출을 차단하고 슬라이드 프로그래밍 (AOP) 에 대한 자신의 생각을 만듭니다.
실현 인터페이스 없음(cglib)
CGLIB는 기능이 강하고 고성능의 코드 생성 패키지이다.이것은 인터페이스를 실현하지 못한 클래스에 에이전트를 제공하고 JDK의 동적 에이전트에 좋은 보충을 제공한다.일반적으로 자바의 동적 에이전트를 사용하여 에이전트를 만들 수 있지만, 에이전트를 만들 클래스가 인터페이스를 실현하지 못하거나, 더 좋은 성능을 위해 CGLIB는 좋은 선택입니다.
GLib 베이스는 ASM 바이트 생성 프레임워크를 사용하고 바이트 기술로 프록시 클래스를 생성하여 자바를 사용하는 것보다 반사 효율이 높다.유일하게 주의해야 할 것은 CGLib이final로 성명하는 방법을 에이전트할 수 없다는 것이다. 왜냐하면 CGLib의 원리는 에이전트된 클래스의 하위 클래스를 동적으로 생성하는 것이기 때문이다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
자바 프로그래밍 사상 읽기 노트 (1)
단일 계승 구조: 모든 대상에 하나의 기본 Object가 있는데 이런 장점은 모든 대상이 기본 유형의 정보를 가지고 있기 때문에 대상의 유형을 확정할 수 없어 교착 상태에 빠지지 않는다는 것이다.이것은 시스템 수준의...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.
반사 클래스 Proxy와 InvocationHandler 리셋 인터페이스를 통해
동적 에이전트는 에이전트 대상을 통해 실제 대상을 포장하고 에이전트 대상을 통해 실제 대상에 대한 요청을 차단한 다음에 에이전트로 실제 대상에게 전송하며 호출을 차단하기 전이나 이후에 자신의 코드를 추가할 수 있도록 한다
동적 에이전트 만들기
(1) 실제 대상이 실현하는 모든 인터페이스를 얻는다.obj가 실제 대상입니다.
Class[] classes=obj.getClass().getInterfaces();
(2) 실제 대상이 속한 클래스를 획득하는 클래스 캐리어
ClassLoader loader=obj.getClass().getClassLoader();
(3) 프록시 객체 작성 자체
이 대상 소속 클래스는java를 실현해야 합니다.lang.reflect 패키지의 InvocationHandler 커넥터입니다.이 인터페이스에서 invoke 방법을 정의했습니다
다음:InvocationHandler 인터페이스를 실현하여 invoke 방법을 다시 쓰고result=method.voke(obj,args) 이 줄은 반사를 통해 목표를 실제 대상에게 호출하여 전송하는 것이다. 전송 전후에 코드를 추가하고 간단한 로그 기능을 실현하면 프록시 클래스가 만들어진다.
package xidian.lili.edu.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class ImpatientProxy implements InvocationHandler{
private Object obj;
public ImpatientProxy(Object obj){
this.obj=obj;
}
@Override
public Object invoke(Object obj, Method method, Object[] args) throws Throwable {
Object result;
long t1=System.currentTimeMillis();
result=method.invoke(obj, args);
long t2=System.currentTimeMillis();
System.out.println("It takes "+(t2-t1)+" millis to invoke "+method.getName());
return result;
}
}
그러면 프록시 클래스 ImpatientProxy의 대상을 사용하려면java를 사용해야 합니다.lang.reflect 패키지의 Proxy 클래스, 이 클래스는 하나의 인터페이스, 하나의 클래스 마운트와 Impatient Proxy 실례 대상이 필요하기 때문에 우리는 에이전트 클래스에 다음과 같은 방법을 추가할 수 있습니다. 이 newInstance의 정적 방법은 우리에게 정적 에이전트 대상을 만들어 줍니다. 이 방법이 되돌아오는 대상은 포장된 대상의 모든 인터페이스를 실현하고 임의의 유형의 대상으로 전환할 수 있습니다.
package xidian.lili.edu.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ImpatientProxy implements InvocationHandler{
private Object obj;
public ImpatientProxy(Object obj){
this.obj=obj;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result;
long t1=System.currentTimeMillis();
result=method.invoke(obj, args);
long t2=System.currentTimeMillis();
System.out.println("It takes "+(t2-t1)+" millis to invoke "+method.getName());
return result;
}
public static Object newInstance(Object obj){
ClassLoader loader=obj.getClass().getClassLoader();
Class[] classes=obj.getClass().getInterfaces();
return Proxy.newProxyInstance(loader, classes, new ImpatientProxy(obj));
}
}
동적 에이전트를 썼을 때, 예를 들어, 대상이 차단하고 싶은 방법에 속하는 인터페이스를 실현하면, 에이전트를 사용하여 대상을 포장할 수 있다.
package xidian.lili.edu.proxy;
import java.util.HashSet;
import java.util.Set;
public class ShowDynamicProxy {
public static void main(String[] args) {
Set s=new HashSet();
// s
s=(Set) ImpatientProxy.newInstance(s);
s.add("hello world");
s.isEmpty();
}
}
방법의 실행 전후에 호출을 차단하고 슬라이드 프로그래밍 (AOP) 에 대한 자신의 생각을 만듭니다.
실현 인터페이스 없음(cglib)
CGLIB는 기능이 강하고 고성능의 코드 생성 패키지이다.이것은 인터페이스를 실현하지 못한 클래스에 에이전트를 제공하고 JDK의 동적 에이전트에 좋은 보충을 제공한다.일반적으로 자바의 동적 에이전트를 사용하여 에이전트를 만들 수 있지만, 에이전트를 만들 클래스가 인터페이스를 실현하지 못하거나, 더 좋은 성능을 위해 CGLIB는 좋은 선택입니다.
GLib 베이스는 ASM 바이트 생성 프레임워크를 사용하고 바이트 기술로 프록시 클래스를 생성하여 자바를 사용하는 것보다 반사 효율이 높다.유일하게 주의해야 할 것은 CGLib이final로 성명하는 방법을 에이전트할 수 없다는 것이다. 왜냐하면 CGLib의 원리는 에이전트된 클래스의 하위 클래스를 동적으로 생성하는 것이기 때문이다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
자바 프로그래밍 사상 읽기 노트 (1)단일 계승 구조: 모든 대상에 하나의 기본 Object가 있는데 이런 장점은 모든 대상이 기본 유형의 정보를 가지고 있기 때문에 대상의 유형을 확정할 수 없어 교착 상태에 빠지지 않는다는 것이다.이것은 시스템 수준의...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.