자바 프 록 시 모드(jdk proxy)

대리
밤 을 들다
예 를 들 어 미국의 대학 이 있 으 면 전 세계 에 학생 을 모집 할 수 있다.그러나 학부 모 에 게 학부 모 가 직접 학 교 를 찾 아 갈 수 없고 학부 모 가 학 교 를 직접 방문 할 능력 이 없다.또는 미국 학교 가 개인 방문 을 받 지 않 는 다 면 이 때 는 유학 중개 가 필요 하 다.
학생,중 개 는 학교의 대리 이다.중개 와 학교 가 해 야 할 일 은 학생 모집 이다.학부 모 에 게 학 교 는 목표 이 고 유학 중 개 는 대리 다.일상생활 에서 많은 대리 의 예 가 있다.예 를 들 어 대리 구 매,부동산 중개,각종 중개,ip 교환,업 체 와 구매자 등 이다.개발 중
같은 경우 도 있 습 니 다.예 를 들 어 당신 은 a 류 가 있 습 니 다.원래 c 류 를 호출 하 는 방법 으로 특정한 기능 을 완성 합 니 다.하지만 c 는 a 호출 을 하지 못 하 게 합 니 다.a---c 를 호출 할 수 없 는 방법.a 와 c 에 b 대 리 를 직접 만 들 고 c 는 b 를 방문 하 게 합 니 다.a-방문 b-방문 c.
원래 의 방문 관계

프 록 시 를 통한 접근 관계

대리 모드 가 뭐 예요?
바 이 두 백과
프 록 시 모드 는 이 대상 에 대한 접근 을 제어 하기 위해 다른 대상 에 게 프 록 시 를 제공 하 는 것 을 말한다.어떤 경우 에 한 대상 이 다른 대상 에 게 적합 하지 않 거나 직접 인용 할 수 없 으 며 대리 대상 은 고객 류 와 목표 대상 사이 에서 중개 역할 을 할 수 있다.
대리 대상 을 사용 하 는 것 은 목표 대상 을 수정 하지 않 는 토대 에서 주 업무 논 리 를 강화 하기 위 한 것 이다.고객 류 가 진정 으로 방문 하고 자 하 는 대상 은 목표 대상 이지 만 고객 류 가 진정 으로 방문 할 수 있 는 대상 은 대리 대상 이다.클 라 이언 트 클래스 가 목표 대상 에 대한 방문 은 방문 에이전트 대상 을 통 해 이 루어 집 니 다.
라 고 적 었 다.물론 대리 류 와 목표 류 는 같은 인 터 페 이 스 를 실현 해 야 한다.
대 리 를 실현 하 는 방식
정적 에이전트
정적 프 록 시 란 프 록 시 클래스 가 프로그램 이 실행 되 기 전에 이미 정 의 된 자바 소스 파일 을 말 합 니 다.목표 클래스 와 의 관 계 는 프로그램 이 실행 되 기 전에 이미 확립 되 었 습 니 다.프로그램 이 실행 되 기 전에 프 록 시 클래스 는.class 파일 로 컴 파일 되 었 습 니 다.
정적 에이전트 의 예 를 들다
수요:사용 자 는 u 반 을 구 매 해 야 합 니 다.u 반 공장 은 따로 분산 구 매 를 접대 하지 않 습 니 다.공장 은 한 번 에 최소 1000 개 이상 을 구 매 하도록 규정 하고 사용 자 는 타 오 바 오의 대리상 이나 마이크로 상 사 를 통 해 구 매 할 수 있 습 니 다.타 오 바 오의 상품 은 모두 u 반 공장 의 대리상 으로 그들 은 u 반 에 대한 판매 업 을 대리 한다.
근무 하 다.사용자 구 매---대리상(타 오 바 오,마이크로 상)---u 반 공장(킹 스 턴,플래시 디 등 서로 다른 공장)
1.업무 인터페이스 정의
업무 인터페이스 UsbSell(목표 인터페이스)을 정의 하 는데 추상 적 인 방법 sell(int amout)이 포함 되 어 있 습 니 다.sell 이 목표 방법 이에 요.

public interface UsbSell {
    /**
     *      ,            
     * @param amount
     * @return
     */
    float sellUsb(int amount);
}
2.인터페이스의 실현 류 정의
목표 클래스 UsbKing Factory 킹 스 턴 U 디스크,이 클래스 는 인 터 페 이 스 를 실현 합 니 다.

import school.xauat.service.UsbSell;
public class UsbKingFactory  implements UsbSell {
    @Override
    /**
     *             
     */
    public float sellUsb(int account) {
        return 75.0f;
    }
}
3.정의 에이전트
TaoBao 는 대리 업 체 가 USB 를 판매 하 는 대리 업 체 입 니 다.

import school.xauat.factory.UsbKingFactory;
import school.xauat.service.UsbSell;
public class Taobao implements UsbSell {
    //                
    private UsbSell factory=new UsbKingFactory();
    @Override
    /**
     *     U    
     */
    public float sellUsb(int account) {
        float price=factory.sellUsb(account);
        //      
        price+=25;
        return price;
    }
}
WeiShang 도 대리 업 체 에서 U 판 을 판매 하 는 업 체 입 니 다.

import school.xauat.factory.UsbKingFactory;
import school.xauat.service.UsbSell;
public class Weishang implements UsbSell {
    //                
    private UsbSell factory=new UsbKingFactory();
    @Override
    public float sellUsb(int amount) {
        float price=factory.sellUsb(amount);
        //      
        price+=15;
        return price;
    }
}
4.클 라 이언 트 호출 자,상품 류 구 매
클 라 이언 트 는 Taobao 와 WeiShang 두 대 리 를 통 해 USB 를 구 매 할 수 있 습 니 다.

import school.xauat.business.Taobao;
import school.xauat.business.Weishang;
public class ShopMain {
    public static void main(String[] args) {
        Taobao taoBao=new Taobao();
        float price=taoBao.sellUsb(1);
        System.out.println(price);
        Weishang weishang=new Weishang();
        float price2=weishang.sellUsb(1);
        System.out.println(price2);
    }
}
이상 의 과정 에 따라 정적 에이전트 의 장단 점 을 분석 합 니 다.
장점:실현 이 간단 하고 이해 하기 쉽다.
단점:
코드 가 복잡 하여 관리 하기 어렵다.
프 록 시 클래스 와 목표 클래스 는 같은 인 터 페 이 스 를 실현 하고 모든 프 록 시 는 목표 클래스 를 실현 하 는 방법 이 필요 하 다.그러면 대량의 코드 가 중복 된다.인터페이스 에 하나의 방법 이 추가 되면 모든 목표 류 가 이 방법 을 실현 해 야 하 는 것 을 제외 하고 모든 대리 류 도 이 방법 을 실현 해 야 한다.코드 유지보수 의 복잡 도 를 증가 시 켰 다.
프 록 시 클래스 는 목표 클래스 에 의존 하고 프 록 시 클래스 가 너무 많 습 니 다.
프 록 시 클래스 는 한 가지 유형의 목표 클래스 에 만 서 비 스 를 제공 합 니 다.여러 가지 유형 에 서 비 스 를 제공 하려 면.반드시 모든 목표 류 를 대리 해 야 합 니 다.정적 대 리 는 프로그램 규모 가 조금 클 때 감당 할 수 없고 대리 류 의 수량 이 너무 많 습 니 다.
동적 에이전트
동적 에이 전 트 는 에이전트 대상 이 프로그램 이 실 행 될 때 JVM 이 반사 메커니즘 에 따라 동적 으로 생 성 되 는 것 을 말한다.동적 프 록 시 는 프 록 시 클래스 의 자바 소스 파일 을 정의 할 필요 가 없습니다.
동적 에이 전 트 는 jdk 가 실행 되 는 동안 동적 으로 class 바이트 코드 를 만 들 고 JVM 에 불 러 옵 니 다.
동적 에이전트 의 실현 방식 은 두 가지 가 있 습 니 다.JDK 동적 대 리 를 사용 하 는 것 과 CGLIB 동적 대 리 를 통 해 사용 하 는 것 입 니 다.
CGLIB 에이전트
CGLIB(Code Generation Library)는 오픈 소스 프로젝트 다.강력 하고 고성능 이 며 질 좋 은 코드 생 성 라 이브 러 리 로 운영 기간 에 자바 류 를 확장 하고 자바 인 터 페 이 스 를 실현 할 수 있 습 니 다.그것 은 Spring AOP 와 같은 많은 AOP 프레임 워 크 에 광범 위 하 게 사용 된다.JDK 의
Proxy 는 프 록 시 를 실현 하고 목표 클래스 와 프 록 시 클래스 가 같은 인 터 페 이 스 를 실현 하도록 요구 합 니 다.목표 클래스 에 인터페이스 가 존재 하지 않 으 면 이 방식 을 사용 할 수 없습니다.그러나 인터페이스 가 없 는 클래스 에 대해 서 는 동적 대 리 를 만 들 려 면 CGLIB 를 사용 해 야 합 니 다.CGLIB 에이전트 의 생 성 원 리 는 목표 클래스 의 하위 클래스 를 생 성 하 는 것 이 고,
자 류 는 강 화 된 것 이 고,이 자 류 의 대상 은 대리 대상 이다.따라서 CGLIB 를 사용 하여 동적 에이 전 트 를 생 성하 고 목표 클래스 가 계승 되 어야 하 며 final 클래스 가 될 수 없 도록 요구 합 니 다.cglib 는 Spring,Hibernate 등 프레임 워 크 에 자주 사용 된다.Cglib 의 대리 효율 은 Jdk 보다 높다.맞다.
cglib 일반 개발 에 서 는 사용 되 지 않 습 니 다.알 아 보면 돼.
JDK 에이전트
jdk 동적 대 리 는 자바 의 반사 체 제 를 바탕 으로 이 루어 집 니 다.jdk 의 인터페이스 와 클래스 를 사용 하여 프 록 시 대상 의 동적 생 성 을 실현 합 니 다.Jdk 의 동적 요구 대상 은 반드시 인 터 페 이 스 를 실현 해 야 합 니 다.이것 은 자바 디자인 의 요구 입 니 다.jdk 1.3 이후 자바 언어 는 자바.lang.reflect 패 키 지 를 통 해 세 가지 종 류 를 제공 합 니 다.
프 록 시 모드 Proxy,Method,InovcationHandler 를 지원 합 니 다.
InvocationHandler 인터페이스
Invocation Handler 인 터 페 이 스 는 호출 프로세서 라 고 하 며,대상 방법 을 완전히 호출 하고 기능 을 강화 합 니 다.프 록 시 대상 을 통 해 대상 인터페이스 에서 의 방법 을 실행 하면 호출 프로세서(Invocation Handler)의 실현 클래스 에 방법의 호출 을 할당 하고 실현 클래스 의 i 를 실행 합 니 다.
nvoke()방법,우 리 는 기능 대 리 를 invoke()방법 에 써 야 합 니 다.

invoke 방법 에서 목표 방법 에 대한 호출 을 차단 할 수 있 습 니 다.이곳 에서 기능 증강 을 진행 하 다.자바 의 동적 대 리 는 반사 메커니즘 위 에 세 워 진 것 이다.Invocation Handler 인터페이스의 클래스 는 목표 클래스 의 주 업무 논 리 를 강화 하 는 데 사용 된다.이 인터페이스 에는 invoke()방법 이 있 습 니 다.
강 한 코드 논 리 는 이 방법 에 정 의 된 것 이다.프 록 시 대상 을 통 해 인터페이스 에 있 는 방법 을 실행 할 때 invoke()방법 을 자동 으로 호출 합 니 다.
invoke()방법 에 대한 소 개 는 다음 과 같 습 니 다.
public Object invoke ( Object proxy, Method method, Object[] args)
proxy:생 성 을 대표 하 는 프 록 시 대상
method:목표 방법 을 대표 합 니 다.
args:목표 방법 을 대표 하 는 매개 변수
첫 번 째 매개 변 수 는 jdk 가 실 행 될 때 값 을 부여 하 는 것 입 니 다.방법 에서 직접 사용 합 니 다.두 번 째 매개 변 수 는 다음 에 소개 합 니 다.세 번 째 매개 변 수 는 방법 이 실 행 된 매개 변수 입 니 다.이 세 번 째 매개 변 수 는 모두 jdk 가 실 행 될 때 값 을 부여 하 는 것 이 므 로 프로그래머 가 제시 할 필요 가 없습니다.
메 소 드 클래스
invoke()방법의 두 번 째 매개 변 수 는 Method 클래스 대상 입 니 다.이 클래스 는 invoke()라 고도 부 르 며 목표 방법 을 호출 할 수 있 습 니 다.이 두 invoke()방법 은 동명 이지 만 무관 하 다.public Object invoke ( Object obj, Object... args)대상
4obj목표 방법 파 라 메 터 를 나타 내 는 것 이 바로 지난 층 invoke 방법의 세 번 째 매개 변수 이다.
이 방법의 역할 은 obj 대상 이 속 한 클래스 를 실행 하 는 방법 을 호출 하 는 것 입 니 다.이 방법 은 호출 자 Method 대상 에 의 해 확 정 됩 니 다.
코드args그 중에서 method 는 이전 invoke 방법의 두 번 째 매개 변수 입 니 다.이렇게 하면 목표 류 의 목표 방법 을 호출 할 수 있다.
프 록 시 클래스
JDK 의 java.lang.reflect.Proxy 클래스 를 통 해 동적 에이 전 트 를 실현 합 니 다.정적 방법 인 newProxyInstance()를 사용 하여 대상,업무 인터페이스 및 호출 프로세서 세 가지 에 따라 동적 에이 전 트 를 자동 으로 생 성 합 니 다.
public static newProxyInstance ( ClassLoader loader, Class[] interfaces, InvocationHandler handler)method.invoke(target, args); loader: , interfaces: , jdk 동적 에이전트 의 실현 절차
jdk 동적 대 리 는 프 록 시 모드 의 실현 방식 으로 프 록 시 인터페이스 만 있 을 수 있 습 니 다.
실현 절차
1.대상 인터페이스 로 인 터 페 이 스 를 새로 만 듭 니 다.
2.인터페이스 에 실현 클래스 를 만 드 는 것 이 목표 클래스 입 니 다.
3.클래스 를 만 들 고 자바.lang.reflect.InvocationHandler 인 터 페 이 스 를 실현 하 며 목표 방법 을 호출 하고 다른 기능 코드 를 추가 합 니 다.
4.동적 프 록 시 대상 을 만 들 고 Proxy.new Proxy Instance()방법 을 사용 하 며 반환 값 을 인터페이스 형식 으로 강제 합 니 다.
예 를 들다
1.목표 인 터 페 이 스 를 만 들 고 목표 인터페이스 기능 을 정의 합 니 다.
2.인터페이스 에 실현 클래스 만 들 기
위의 두 단 계 는 정적 에이전트 와 같 습 니 다.
3.InvocationHandler 인터페이스의 실현 클래스 를 만 들 고 목표 방법 을 호출 하 며 다른 코드 기능 을 추가 합 니 다.

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class MySellHandler implements InvocationHandler {
    //    
    private Object target=null;
    public MySellHandler(Object target){
        this.target=target;
    }
    @Override
    /**
     *   InvocationHandler      , invoke           
     *      -      
     *      -    
     */
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object result=null;
        result=method.invoke(target,args);

        //    
        //      ,            25 
        if (result!=null){
            float price=(float)result;
            price=price+25;
            result=price;
        }
        return result;
    }
}
여기 target 대상 은 정적 에이전트 의 TaoBao 와 WeiShang 에 해당 합 니 다.
4.아 날로 그 클 라 이언 트 가 U 디스크 를 구 매 하고 proxy.newProxyInstance 를 사용 하여 프 록 시 프 록 시 대상 을 만 들 고 반환 값 을 대상 인터페이스 형식 으로 합 니 다.

import school.xauat.factory.UsbKingFactory;
import school.xauat.handler.MySellHandler;
import school.xauat.service.UsbSell;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
public class MainShop {
    public static void main(String[] args) throws Exception {
        //      
        Class c=UsbKingFactory.class;
        Object obj=c.newInstance();
        //          
        ClassLoader loader =UsbKingFactory.class.getClassLoader();
        //            
        Class<?>[]interfaces=obj.getClass().getInterfaces();
        //  InvocationHandler  
        InvocationHandler handler=new MySellHandler(obj);
        //      
        UsbSell proxy=(UsbSell) Proxy.newProxyInstance(loader,interfaces,handler);
        //          
        float price=proxy.sell(1);
        System.out.println(price);
    }
}
정적 에이전트

동적 에이전트

UML 그림

총결산
이 글 은 여기까지 입 니 다.당신 에 게 도움 을 줄 수 있 기 를 바 랍 니 다.또한 당신 이 우리 의 더 많은 내용 에 관심 을 가 져 주 실 수 있 기 를 바 랍 니 다!

좋은 웹페이지 즐겨찾기