자바 동적 에이전트 깊이 이해

retrofit 는 디 결합 성 이 매우 높 은 네트워크 요청 프레임 워 크 입 니 다.최근 에 연구 할 때 동적 대리 라 는 매우 강력 하고 실 용적 인 기술 을 발 견 했 습 니 다.이 글 은 retrofit 의 선행 지식 으로 사람들 에 게 동적 대리 가 어떤 응용 장면 이 있 는 지,동적 대리 가 무엇 인지,어떻게 사용 하 는 지,그 한계점 이 어디 에 있 는 지 알려 줄 것 입 니 다.
동적 에이전트 의 응용 장면
1.AOP―절단면 프로 그래 밍,프로그램 디 결합
즉,일부 내부 의 방법 에 대해 실행 전과 실행 후에 공 통 된 조작 을 하고 방법 에서 맞 춤 형 조작 을 수행 할 때 동적 대 리 를 사용 하 는 것 이다.업 무량 이 많 을 때 코드 량 을 낮 추고 유지 가능성 을 높 일 수 있다.
2.세 번 째 라 이브 러 리 의 일부 방법 을 사용자 정의 하려 면
나 는 제3자 라 이브 러 리 를 인 용 했 지만 그의 일부 방법 은 나의 수 요 를 만족 시 키 지 못 했다.나 는 스스로 그 몇 가지 방법 을 다시 쓰 거나 방법 전후 에 특수 한 조작 인 동적 대 리 를 추가 하고 싶다.그러나 주의해 야 할 것 은 이 방법 들 이 한계 가 있다 는 점 이다.나 는 잠시 후에 설명 할 것 이다.
동적 에이전트 가 무엇 입 니까?

이상 의 그림 은 너무 추상 적 이어서 우 리 는 생활 속 의 예 에서 부터 착안한다.
만약 당신 이 큰 집주인 이 라면(대리인 에 게)세 를 놓 고 싶 은 집 이 많 습 니 다.그리고 세입 자 를 찾 는 것 이 너무 번 거 로 워 서 스스로 하고 싶 지 않 습 니 다.그래서 당신 은 한 사람 을 찾 아 당신(대리인)을 대리 하고 이 물건 들 을 관리 해 주 십시오.이 사람(대리인,즉 중개)은 당신 을 도와 집 을 임대 할 때 당신 에 게 해당 하 는 중개 비 를 받 습 니 다.세입 자 에 게 중 개 는 집주인 이 고 당신 을 대신 해서 뭔 가 를 하 는 것 입 니 다.
이상 은 하나의 대리 의 예 입 니 다.그 는 왜 동적 대리 라 고 부 릅 니까?'동적'두 글꼴 은 현재 어디 에 있 습 니까?
우 리 는 이렇게 생각 할 수 있 습 니 다.만약 에 당신 의 모든 집 을 대리인 에 게 부탁 하여 관리 해 달라 고 할 수 있 습 니 다.만약 에 당신 이 집 을 한 채 더 임대 하고 싶 을 때 하 나 를 더 청해 야 합 니 다.그러면 당신 은 많은 대리인 을 초대 하고 높 은 중개 비용 을 들 일 것 입 니 다.이것 은 흔히 말 하 는'정태 적 인 대리'로 볼 수 있 습 니 다.
그러나 만약 에 우리 가 모든 집 을 중개 에 게 맡 겨 대리 한다 면 그 는 여러 채 의 집 사이 에서 동태 적 으로 신분 을 전환 시 켜 모든 세입 자 에 게 대처 하도록 도와 줄 것 이다.이것 이 바로'동적 대리'의 과정 이다.동적 에이전트 의 큰 특징 은 컴 파일 단계 에 에이전트 클래스 가 실행 되 지 않 을 때 만 에이전트 클래스 를 생 성 하 는 것 이다.
코드 로 한번 볼 게 요.
주택 임대 작업

/**
*      
**/
public interface RentHouse {
void rent();//    
void charge(String str);//      
}
집주인

public class HouseOwner implements RentHouse {
public void rent() {
  System.out.println("I want to rent my house");
}

public void charge(String str) {
  System.out.println("You get : " + str + " RMB HouseCharge.");
}
}

중개 하 다.

public class DynamicProxy implements InvocationHandler {

//               ,   
private Object subject;

//     ,              
public DynamicProxy(Object subject) {
  this.subject = subject;
}

@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
  //                       ,       
  System.out.println("before "+method.getName()+" house");

  System.out.println("Method:" + method.getName());

  //          charge      100    
  if (method.getName().equals("charge")) {

    method.invoke(subject, args);
    System.out.println("I will get 100 RMB ProxyCharge.");

  } else {
    //                 ,               handler   invoke       
    method.invoke(subject, args);
  }

  //                        
  System.out.println("after "+method.getName()+" house");

  return null;
}
}

손님.

public class Client {
public static void main(String[] args)
{
  //            --  
  HouseOwner houseOwner = new HouseOwner();

  //             ,        ,                 
  InvocationHandler handler = new DynamicProxy(houseOwner);

  /*
   *   Proxy newProxyInstance            ,          
   *       handler.getClass().getClassLoader() ,      handler    ClassLoader            
   *      realSubject.getClass().getInterfaces(),                         ,             ,                
   *      handler,                    InvocationHandler      
   */
  RentHouse rentHouse = (RentHouse) Proxy.newProxyInstance(handler.getClass().getClassLoader(), houseOwner
      .getClass().getInterfaces(), handler);//       ,  

  System.out.println(rentHouse.getClass().getName());
  rentHouse.rent();
  rentHouse.charge("10000");
}
}

출력 을 한번 볼 게 요.

com.sun.proxy.$Proxy0
before rent house
Method:rent
I want to rent my house
after rent house
before charge house
Method:charge
You get : 10000 RMB HouseCharge.
I will get 100 RMB ProxyCharge.
after charge house

Process finished with exit code 0
출력 에는 before rent house 와 after rent house 가 있 습 니 다.방법 전후 에 작업 을 추가 할 수 있 음 을 설명 합 니 다.출력 I will get 100 RMB Proxy Charge.중 개 는 100 위안 의 중개 비 를 받 았 다.이 는 우리 가 조작 을 늘 릴 수 있 을 뿐만 아니 라 이 방법 을 바 꾸 거나 직접 실행 하지 않 게 할 수 있다 는 것 을 의미한다.
처음에 코드 를 보면 궁금 증 이 많 을 수 있 습 니 다.우 리 는 다음 과 같은 내용 을 통 해 동적 대 리 를 어떻게 사용 해 야 하 는 지 보 겠 습 니 다.
동적 대 리 는 어떻게 사용 해 야 합 니까?
자바 의 동적 에이전트 에는 두 가지 중요 한 클래스 와 인터페이스 가 있 습 니 다.하 나 는 Invocation Handler(Interface)이 고 다른 하 나 는 Proxy(Class)입 니 다.이 클래스 와 인 터 페 이 스 는 우리 의 동적 대 리 를 실현 하 는 데 필요 한 것 입 니 다.
모든 동적 프 록 시 클래스 는 InvocationHandler 라 는 인터페이스(코드 의 중개)를 실현 해 야 합 니 다.또한 모든 프 록 시 클래스 의 인 스 턴 스 는 하나의 handler 와 연결 되 어 있 습 니 다.우리 가 프 록 시 대상 을 통 해 하나의 방법 을 호출 할 때,이 방법의 호출 은 Invocation Handler 라 는 인터페이스의 invoke(방법 에 대한 강 화 는 여기에 쓰 여 있 습 니 다)방법 으로 호출 됩 니 다.

Object invoke(Object proxy, Method method, Object[] args) throws Throwable
우 리 는 이 방법 이 모두 세 개의 인 자 를 받 아들 이 는 것 을 보 았 다.그러면 이 세 개의 인 자 는 각각 무엇 을 대표 합 니까?

Object invoke(Object proxy, Method method, Object[] args) throws Throwable
//proxy:                
//method:                      Method  
//args:                      
이제 프 록 시 이런 거 한번 볼 게 요.

public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces,  InvocationHandler h)  throws IllegalArgumentException
프 록 시 라 는 클래스 의 역할 은 프 록 시 대상 을 동적 으로 만 드 는 클래스 입 니 다.많은 방법 을 제공 하지만 우리 가 가장 많이 사용 하 는 것 은 new Proxy Instance 라 는 방법 입 니 다.

public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces,  InvocationHandler h)  throws IllegalArgumentException
이 방법의 역할 은 바로 동태 적 인 대리 대상 을 얻 고 세 개의 매개 변 수 를 받 는 것 이다.우 리 는 이 세 개의 매개 변수 가 대표 하 는 의 미 를 살 펴 보 자.

public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException

//loader:  ClassLoader  ,      ClassLoader               
//interfaces:  Interface     ,                        ,            ,                 (  ),                
//h:  InvocationHandler  ,                      ,       InvocationHandler   

이렇게 되면 위 에서 제시 한 코드 를 결합 하면 우 리 는 동적 에이전트 의 사용 방법 을 알 수 있다.
동적 에이전트 의 한계 성
동적 에이전트 의 사용 방법 에서 우 리 는 사실 강 화 될 수 있 는 방법 은 모두 핑 계 를 실현 한 것 임 을 알 수 있다.(핑 계 를 실현 하지 않 는 Public 방법 도 피 에이전트 류 를 계승 하여 사용 할 수 있다)코드 중의 House Owner 는 Rent House 를 계승 했다.프 라이 빗 방법 JDK 의 동적 에이전트 에 대해 서 는 어 쩔 수 없습니다!
이상 의 동적 에이 전 트 는 JDK 의 것 입 니 다.자바 프로젝트 에 대해 유명한 CGLib 도 있 습 니 다.그러나 안 타 깝 게 도 CGLib 는 안 드 로 이 드 에서 사용 할 수 없습니다.안 드 로 이 드 가상 머 신 은 상대 적 으로 jvm 과 차이 가 있 습 니 다.
종결 어
동적 에이전트 의 사용 장면 은 이런 것 뿐만 이 아니 라 내부 원 리 는 앞으로 의 글 에서 소개 되 지만 응용 류 반사 임시 생 성 에이전트 라 는 체 제 는 성능 에 어느 정도 영향 을 미 칠 것 이 라 고 결정 한다.본 고 는 retrofit 원리 로 서 의 선행 글 이 너무 상세 하지 않 습 니 다.만약 누락 과 오류 가 있 으 면 지적 해 주 십시오!
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

좋은 웹페이지 즐겨찾기