Java java지도 시간 Java에서 동적 프록시 구현에 대한 튜토리얼

Java에서 동적 프록시 구현에 대한 튜토리얼

Jun 30, 2017 am 09:52 AM
invoke 질문

다음 내용은 일부 인터넷에 있는 내용을 바탕으로 작성되었으며 원작자에게 감사의 말씀을 전하고 싶습니다!

Java에서 동적 프록시 구현의 핵심은 Proxy와 InvocationHandler라는 두 가지입니다. InvocationHandler 인터페이스의 호출 메소드부터 시작하여 Java가 동적 프록시를 구현하는 방법을 간략하게 설명하겠습니다. N i 먼저 Invoke 메소드의 무결성은 다음과 같습니다. java code

Public Object Invoke (Object Proxy, Method Method, Object [] ARGS)
Throws Throwable
Java에서 동적 프록시 구현에 대한 튜토리얼
{
  1. method.invoke(obj, args);      

    return
  2. null;                               즉, ARGS를 실행해야 하는 메서드는 다음과 같습니다. 메소드의 매개변수입니다. 이 매개변수는 무엇인가요? 위의 Invoke() 메소드 구현은 상대적으로 표준적인 형식입니다. 여기서는 프록시 매개변수가 사용되지 않습니다. 다음과 같이 JDK 문서에서 프록시에 대한 설명을 확인하세요.
  3. Java code
  4. pr oxy 인터페이스 중 하나를 통해 프록시 인스턴스에 대한 메서드 호출은 다음과 같습니다. 인스턴스 호출 핸들러의 호출 메소드로 전달되어 프록시 인스턴스, 호출된 메소드를 식별하는 java.lang.reflect.Method 객체 및 인수를 포함하는 Object 유형 배열을 전달합니다. 이를 통해 위의 추측이 정확하다는 것을 알 수 있으며 프록시 매개변수가 프록시 클래스의 인스턴스로 전달된다는 것도 알 수 있습니다.

  5. 설명의 편의를 위해 동적 프록시를 구현하는 간단한 예를 들어보겠습니다. ㅋㅋ           

public

interface 제목 {

public
void request()

Java에서 동적 프록시 구현에 대한 튜토리얼}






Java 코드

  1. //실제 역할: Subject의 request() 메소드 구현

  2. public class RealSubject implements Subject{

  3. 공개 요청 취소(){

  4. System.out.println("실제 주제에서.")

  5. }

  6. }


Java 코드
Java에서 동적 프록시 구현에 대한 튜토리얼
  1. //구현된 InvocationHandler

  2. public class DynamicSubject 구현 vocationHandler

  3. {

  4. 개인 개체 obj; //이것은 캡슐화된 개체가 개체 유형이며 모든 유형의 개체를 허용합니다. 공개 동적 주제 (객체 obj)

  5. {

  6. this.obj = ob j;

  7. }

  8. // 우리가 명시적으로 부르는 것이 아닙니다

  9. public Object Invoke(Object Proxy, Method method, Object[] args)

    throwable
  10. {

    System.out.println(
  11. "호출하기 전 " + 메소드)
  12. method.invoke(obj, args); //------> 이 단계에 대한 자세한 내용은 다음 문서를 참조하세요. Java는 리플렉션 메커니즘을 통해 특정 함수를 호출합니다. 읽은 후에.

  13. System.out.println("" + 메소드 호출 후)

  14. return

  15. }

  16. )

    1. //클라이언트: 프록시 인스턴스를 생성하고 request() 메서드를 호출했습니다.

    2. public class Client {

    3. public static void main(String [ ] args) Throwable 던지기{

    4.                                                                         ​Subject rs=new RealSubject();//여기서 프록시를 지정하세요. 클래스

    5. InvocationHandler ds=
    6. new DynamicSubject(rs)

      클래스> cls=rs.getClass();

    7. ​​​​
    8. //다음은 일회용 프록시 생성

    9. +                             Interfaces(), ds);
    10. /여기서 주체가 프록시의 인스턴스임을 증명할 수 있습니다.

      시스템아웃 .println(subject
    11. instanceof Proxy);
    12.        

      //여기서 주체의 Class 클래스가 $Proxy0임을 알 수 있습니다. 이 클래스는 Proxy를 상속하고

    13. toString());

    14. System.out.print(
    15. "제목의 속성은 다음과 같습니다: ")

    16. Field [] field=subject.getClass () .getDeclaredFields();
    17.                                                 

    18.           System.out.print("n"+" 주제의 메소드는 다음과 같습니다: ") ().getDeclaredMethods( ); ㅠㅠ

    19. System.out.println(

      "n"+

      "subject의 상위 클래스는 "+subject.getClass().getSuperclass());
    20. System.out.print("n"+

      "주제에 의해 구현된 인터페이스: "); subject.getClass().getInterfaces();
    21.                                                   ~ 8                                                           
    22. }

    23. System.out.println("nn"+"작업 결과: "); Subject.request()

    24. }
    25. )
    26. 실행 결과는 다음과 같습니다. 여기서 패키지 이름은 생략됩니다. * **

true 대신 subject의 클래스 클래스는 다음과 같습니다. class $Proxy0
subject의 속성 m1, m3, m0, m2,
주제의 메서드는 request , hashCode, equals, toString,

주체의 상위 클래스: class java.lang.reflect.Proxy
subject Implements 인터페이스: cn.edu.ustc.dynamicproxy.Subject, Java에서 동적 프록시 구현에 대한 튜토리얼
  1. 실행 결과는 다음과 같습니다.
  2. public abstract void를 호출하기 전 ***.Subject.request()
  3. 실제에서 subject. . 동적 프록시에 대한 혼란의 근본 원인은 위의 subject.request()를 오해했기 때문입니다. 적어도 표면적으로는 혼란스러웠습니다. 나는 마지막 호출에서 얽혀 있었습니다. request()는 Invoke()와 연결되어 있으며, Invoke는 요청이 존재한다는 것을 어떻게 알 수 있습니까? 실제로 위의 true 및 클래스 $Proxy0은 아래에 언급된 $Proxy0의 소스 코드와 함께 동적 프록시에 대한 의문을 완전히 해결할 수 있습니다.
  4. 위의 코드와 결과에서 볼 수 있듯이, Invoke() 메소드를 명시적으로 호출하지 않았으나, 실제로 이 메소드가 실행되었습니다. 전체 프로세스를 분석해 보겠습니다.

  5. 클라이언트의 코드에서 newProxyInstance 메서드를 획기적인 방법으로 사용할 수 있습니다. 먼저 Proxy 클래스에 있는 newProxyInstance 메서드의 소스 코드를 살펴보겠습니다.

  6. Java 코드

    1. public static Object newProxyInstance(ClassLoader loader,  

    2.          Class>[] 인터페이스,  

    3.         InvocationHandler h) 

    4. IllegalArgumentException이 발생함  

    5. {  

    6.     if (h == null) {  

    7.         throw new NullPointerException();  

    8.     }  

    9.     /* 

    10.      * 지정된 프록시 조회 또는 생성 수업. 

    11.      */  

    12.     클래스 cl = getProxyClass(로더, 인터페이스);  

    13.     /* 

    14.      * 지정된 호출 핸들러를 사용하여 생성자를 호출합니다. ㅋㅋㅋ

                  * Proxy源码开始有这样적정义: 
    15.            * 비공개 최종 정적 클래스 [] constructorParams = { InvocationHandler.class }; ㅋㅋㅋ
    16.         생성자 단점 = cl.getConstructor(constructorParams);  

    17.         
    18. return(객체) cons.newInstance(

      new Object[] { h });  

    19.     } catch (NoSuchMethodException e) {  

    20.         throw new InternalError(e.toString());  

    21.     } 

      catch(IllegalAccessException e) {  
    22.        

      throw 
    23. new InternalError(e.toString());  
    24.     } catch (InstantiationException e) {  

    25.        
    26. throw 

      new InternalError(e.toString());  

    27.     } catch(InvocationTargetException e) {  

    28.         
    29. throw 

      new InternalError(e.toString());  

    30.     }  }  



    31. Proxy.newProxyInstance(ClassLoader loader, Class>[] 인터페이스, InvocationHandler h)는 다음 작업을 수행합니다.
      (1) 매개변수 로더 및 인터페이스 호출 메서드에 따라 getProxyClass(loader, 인터페이스)는 $Proxy0 프록시 클래스를 생성합니다. $Proxy0 클래스는 인터페이스 인터페이스를 구현하고 Proxy 클래스를 상속합니다.
                            (2) $Proxy0을 인스턴스화하고 생성자에 DynamicSubject를 전달한 다음 $Proxy0을 호출합니다. 상위 클래스의 프록시는 다음과 같이 h에 값을 할당합니다.
      클래스 프록시{
      InvocationHandler h=
      null;
      protected Proxy(InvocationHandler h) {

      Java에서 동적 프록시 구현에 대한 튜토리얼 }
      1. ...

        }
      2. Proxy를 상속하는 $Proxy0의 소스 코드를 살펴보겠습니다.
      3. Java 코드
        1. public final class $Proxy0 extends Proxy implements Subject {  

        2.     private static Method m1;  

        3.     비공개 정적 메소드 m0;  

        4.     비공개 정적 방법 m3;  

        5.     비공개 정적 방법 m2;  

        6.     정적 {  

        7.         시도해보세요 {  

        8.             m1 = Class.forName("java.lang.Object").getMethod("equals",  

        9.                    new Class[] { Class.forName("java.lang.Object") });  

        10.             m0 = Class.forName("java.lang.Object").getMethod("hashCode",  

        11.                     새 수업[0]);  

        12.             m3 = Class.forName("***.RealSubject").getMethod("요청",  

        13.                     새 수업[0]);  

        14.             m2 = Class.forName("java.lang.Object").getMethod("toString",  

        15.                    

          새 수업[0]);  

        16.         } 

          catch (NoSuchMethodException nosuchmethodexception) {  

        17.            

          throw new NoSuchMethodError(nosuchmethodexception.getMessage());  

        18.         } 

          catch (ClassNotFoundException classnotfoundException) {  

        19.            

          throw new NoClassDefFoundError(classnotfoundException.getMessage() );  

        20.         }  

        21.     } 

          //static  

        22.     

          public $Proxy0(Invoca tionHandler 호출 처리기) {  

        23.         

          super(invocationhandler);  

        24.     }  

        25.     

          @Override  

        26.     

          public final 부울 같음(객체 obj) {  

        27.         

          시도해 보세요 {  

        28.            return((Boolean) super.h.invoke(this, m1, new Object[] { obj })) .booleanValue();  

        29.         } catch(Throwable throwable) {  

        30.            throw new UndeclaredThrowableException(throwable);  

        31.         }  

        32.     }  

        33.     @Override  

        34.     public final int hashCode() {  

        35.         시도해 보세요 {  

        36.            return((정수) super.h.invoke(this, m0, null)).intValue();  

        37.         } catch(Throwable throwable) {  

        38.            throw new UndeclaredThrowableException(throwable);  

        39.         }  

        40.     }  

        41.     public final void request() {  

        42.         시도해 보세요 {  

        43.            super.h. 호출(this, m3, null);  

        44.             반품;  

        45.         } catch(오류 e) {  

        46.         } catch(던지기 가능) {  

        47.             throw new UndeclaredThrowableException(throwable);  

        48.         }  

        49.     }  

        50.     @Override  

        51.     public final String toString() {  

        52.         try {  

        53.             return(문자열) super.h.invoke(this, m2, null);  

        54.         } catch(Throwable throwable) {  

        55.            throw new UndeclaredThrowableException(throwable);  

        56.         }  

        57.     }  

        58. }  



      그런 다음 얻은 $Proxy0 인스턴스를 Subject로 캐스팅하고 참조를 subject에 할당합니다. subject.request() 메소드가 실행되면 $Proxy0 클래스의 request() 메소드가 호출된 후 상위 클래스 Proxy에 있는 h의 호출() 메소드, 즉 InvocationHandler.invoke()가 호출된다.

      PS: 1. 설명해야 할 한 가지는 Proxy 클래스의 getProxyClass 메서드가 Proxy 클래스 클래스를 반환한다는 것입니다. 이렇게 설명하는 이유는, 반환된 것이 "프록시된 클래스의 클래스"라고 생각하고 처음에 저레벨 실수를 했기 때문입니다--! getProxyClass의 소스 코드를 살펴보는 것이 좋습니다. 코드가 매우 깁니다. =
      2. $Proxy0의 소스 코드를 보면 동적 프록시 클래스가 명시적으로 정의된 인터페이스의 메서드를 프록시할 뿐만 아니라 Java 루트 클래스 Object에서 상속받은 equals() 및 hashcode()도 프록시하는 것을 볼 수 있습니다. , toString() 및 이 세 가지 메서드만 있습니다.

      Q: 지금까지 여전히 의문점이 있습니다. Invoke 메소드의 첫 번째 매개변수는 Proxy의 인스턴스(정확히 말하면 $Proxy0의 인스턴스가 최종적으로 사용됩니다)인데, 그 용도는 무엇인가요? 즉, 프로그램이 그 효과를 어떻게 나타내는가?
      A: 현재 수준에서 이 프록시 매개변수는 전체 동적 프록시 메커니즘에서 InvocationHandler의 호출 메소드의 프록시 매개변수가 사용되지 않습니다. 전달된 매개변수는 실제로 프록시 클래스의 인스턴스입니다. 프로그래머가 호출 메서드에서 리플렉션을 사용하여 프록시 클래스에 대한 일부 정보를 얻을 수 있도록 하는 것일 수도 있다고 생각합니다.

위 내용은 Java에서 동적 프록시 구현에 대한 튜토리얼의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

AI Hentai Generator

AI Hentai Generator

AI Hentai를 무료로 생성하십시오.

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

C++ 코드에 나타나는 '오류: 'ClassName' 클래스 재정의' 문제 해결 C++ 코드에 나타나는 '오류: 'ClassName' 클래스 재정의' 문제 해결 Aug 25, 2023 pm 06:01 PM

C++ 코드에서 "error:redefinitionofclass'ClassName'" 문제를 해결하세요. C++ 프로그래밍에서는 다양한 컴파일 오류가 자주 발생합니다. 일반적인 오류 중 하나는 "error:redefinitionofclass 'ClassName'"('ClassName' 클래스의 재정의 오류)입니다. 이 오류는 일반적으로 동일한 클래스가 여러 번 정의될 때 발생합니다. 이 기사는

클러스터링 알고리즘의 클러스터링 효과 평가 문제 클러스터링 알고리즘의 클러스터링 효과 평가 문제 Oct 10, 2023 pm 01:12 PM

클러스터링 알고리즘에서 클러스터링 효과 평가 문제에는 특정 코드 예제가 필요합니다. 클러스터링은 데이터를 클러스터링하여 유사한 샘플을 하나의 범주로 그룹화하는 비지도 학습 방법입니다. 클러스터링 알고리즘에서는 클러스터링의 효과를 어떻게 평가하는가가 중요한 문제입니다. 이 기사에서는 일반적으로 사용되는 몇 가지 클러스터링 효과 평가 지표를 소개하고 해당 코드 예제를 제공합니다. 1. 클러스터링 효과 평가 지수 실루엣 계수 실루엣 계수는 표본의 근접성 및 다른 클러스터와의 분리 정도를 계산하여 클러스터링 효과를 평가합니다.

Windows 10에서 Steam을 다운로드할 수 없으면 어떻게 해야 하나요? Windows 10에서 Steam을 다운로드할 수 없으면 어떻게 해야 하나요? Jul 07, 2023 pm 01:37 PM

Steam은 고품질 게임이 많은 매우 인기 있는 게임 플랫폼이지만 일부 Win10 사용자는 Steam을 다운로드할 수 없다고 보고합니다. 무슨 일이 일어나고 있나요? 사용자의 IPv4 서버 주소가 제대로 설정되지 않았을 가능성이 높습니다. 이 문제를 해결하려면 호환 모드에서 Steam을 설치한 다음 수동으로 DNS 서버를 114.114.114.114로 수정하면 나중에 다운로드할 수 있습니다. Win10에서 Steam을 다운로드할 수 없는 경우 해결 방법: Win10에서는 호환 모드로 설치를 시도할 수 있으며, 업데이트 후에는 호환 모드를 꺼야 합니다. 그렇지 않으면 웹 페이지가 로드되지 않습니다. 호환 모드에서 프로그램을 실행하려면 프로그램 설치 속성을 클릭하세요. 메모리, 전력을 늘리려면 다시 시작하세요.

일반적인 iPhone 문제를 진단하는 방법을 가르쳐주세요. 일반적인 iPhone 문제를 진단하는 방법을 가르쳐주세요. Dec 03, 2023 am 08:15 AM

강력한 성능과 다재다능한 기능으로 잘 알려진 iPhone은 복잡한 전자 장치에서 흔히 발생하는 문제인 가끔씩 발생하는 문제나 기술적인 어려움으로부터 자유롭지 않습니다. iPhone 문제를 경험하면 실망스러울 수 있지만 일반적으로 알람은 필요하지 않습니다. 이 종합 가이드에서는 iPhone 사용과 관련하여 가장 일반적으로 직면하는 문제 중 일부를 쉽게 설명하는 것을 목표로 합니다. 당사의 단계별 접근 방식은 이러한 일반적인 문제를 해결하는 데 도움을 주고 장비를 최상의 작동 순서로 되돌릴 수 있는 실용적인 솔루션과 문제 해결 팁을 제공하도록 설계되었습니다. 결함이 있거나 더 복잡한 문제에 직면하더라도 이 문서는 문제를 효과적으로 해결하는 데 도움이 될 수 있습니다. 일반적인 문제 해결 팁 특정 문제 해결 단계를 진행하기 전에 다음은 몇 가지 유용한 정보입니다.

PHP 오류 해결: 상위 클래스를 상속할 때 발생하는 문제 PHP 오류 해결: 상위 클래스를 상속할 때 발생하는 문제 Aug 17, 2023 pm 01:33 PM

PHP 오류 해결: 상위 클래스 상속 시 발생하는 문제 PHP에서 상속은 객체 지향 프로그래밍의 중요한 기능입니다. 상속을 통해 기존 코드를 재사용하고 원본 코드를 수정하지 않고도 확장하고 개선할 수 있습니다. 상속은 개발에 널리 사용되지만 부모 클래스에서 상속할 때 가끔 오류 문제가 발생할 수 있습니다. 이 문서에서는 부모 클래스에서 상속할 때 발생하는 일반적인 문제를 해결하는 데 중점을 두고 해당 코드 예제를 제공합니다. 질문 1: 시스템이 상위 클래스를 상속하는 과정에서 상위 클래스를 찾을 수 없습니다.

jQuery가 양식 요소 값을 얻을 수 없는 문제를 해결하는 방법 jQuery가 양식 요소 값을 얻을 수 없는 문제를 해결하는 방법 Feb 19, 2024 pm 02:01 PM

jQuery.val()을 사용할 수 없는 문제를 해결하려면 구체적인 코드 예제가 필요합니다. 프론트 엔드 개발자에게는 jQuery를 사용하는 것이 일반적인 작업 중 하나입니다. 그중에서도 .val() 메서드를 사용하여 양식 요소의 값을 가져오거나 설정하는 것은 매우 일반적인 작업입니다. 그러나 특정한 경우에는 .val() 메서드를 사용하지 못하는 문제가 발생할 수 있습니다. 이 문서에서는 몇 가지 일반적인 상황과 해결 방법을 소개하고 구체적인 코드 예제를 제공합니다. 문제 설명 jQuery를 사용하여 프런트 엔드 페이지를 개발할 때 때때로 다음과 같은 문제가 발생할 수 있습니다.

약한 지도 학습의 라벨 획득 문제 약한 지도 학습의 라벨 획득 문제 Oct 08, 2023 am 09:18 AM

약한 지도 학습의 라벨 획득 문제에는 특정 코드 예제가 필요합니다. 소개: 약한 지도 학습은 훈련에 약한 라벨을 사용하는 기계 학습 방법입니다. 기존 지도 학습과 달리 약한 지도 학습은 각 샘플에 정확한 라벨이 필요한 것이 아니라 모델을 훈련하는 데 더 적은 수의 라벨만 사용하면 됩니다. 그러나 약한 지도 학습에서는 약한 레이블로부터 유용한 정보를 정확하게 얻는 방법이 핵심 문제입니다. 이 기사에서는 약한 지도 학습의 레이블 획득 문제를 소개하고 구체적인 코드 예제를 제공합니다. 약한 지도 학습의 라벨 획득 문제 소개:

머신러닝 모델의 일반화 능력 문제 머신러닝 모델의 일반화 능력 문제 Oct 08, 2023 am 10:46 AM

기계 학습 모델의 일반화 기능에는 특정 코드 예제가 필요합니다. 기계 학습의 개발 및 적용이 점점 더 널리 보급됨에 따라 사람들은 기계 학습 모델의 일반화 기능에 점점 더 많은 관심을 기울이고 있습니다. 일반화 능력은 레이블이 지정되지 않은 데이터에 대한 기계 학습 모델의 예측 능력을 의미하며, 현실 세계에서 모델의 적응성으로도 이해될 수 있습니다. 좋은 머신러닝 모델은 높은 일반화 능력을 갖추고 새로운 데이터에 대해 정확한 예측을 할 수 있어야 합니다. 그러나 실제 응용에서는 훈련 세트에서는 잘 수행되지만 테스트 세트에서는 실패하거나 실제 모델에서 실패하는 모델을 자주 접하게 됩니다.

See all articles