찾다
Javajava지도 시간Java 동적 프록시 적용에 대한 자세한 설명

동적 프록시는 실제로 지정한 모든 인터페이스를 기반으로 클래스를 동적으로 생성하는 java.lang.reflect.Proxy 클래스입니다. 바이트이면 이 클래스는 Proxy 클래스를 상속하고 지정한 모든 인터페이스(매개변수에 전달한 인터페이스 배열)를 구현한 다음 지정한 클래스로더를 사용합니다. 수업 byte가 시스템에 로드되고 최종적으로 그러한 클래스의 객체가 생성되고 invocationHandler, 즉 모든 인터페이스에 해당하는 Method 멤버와 같은 객체의 일부 값이 초기화됩니다. 초기화 후 개체는 호출 클라이언트로 반환됩니다. 이러한 방식으로 클라이언트는 모든 인터페이스를 구현하는 프록시 개체를 얻습니다. 분석 예를 참조하세요.

package com.fans.common.proxy;
public interface BusinessProcessor {
  public void processBusiness();
}
package com.fans.common.proxy;
/**
 * 业务处理类
 * @author fanshadoop
 *
 */
public class BusinessProcessorImpl implements BusinessProcessor {
 @Override
 public void processBusiness() {
  System.out.println("processing business.....");
 }
}
package com.fans.common.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
/**
 * 业务代理类
 * @author fanshadoop
 *
 */
public class BusinessProcessorHandler implements InvocationHandler {
 private Object target = null;
 BusinessProcessorHandler(Object target) {
  this.target = target;
 }
 public Object invoke(Object proxy, Method method, Object[] args)
   throws Throwable {
  System.out
    .println("You can do something here before process your business");
  Object result = method.invoke(target, args);
  System.out
    .println("You can do something here after process your business");
  return result;
 }
}
package com.fans.common.proxy;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Proxy;
public class Test {
 /**
  * @param args
  */
 public static void main(String[] args) {
  BusinessProcessorImpl bpimpl = new BusinessProcessorImpl();
  BusinessProcessorHandler handler = new BusinessProcessorHandler(bpimpl);
  BusinessProcessor bp = (BusinessProcessor) Proxy.newProxyInstance(
    bpimpl.getClass().getClassLoader(), bpimpl.getClass()
      .getInterfaces(), handler);
  bp.processBusiness();
  System.out.println(bp.getClass().getName());
  printClassDefinition(bp.getClass());
 }
 public static String getModifier(int modifier) {
  String result = "";
  switch (modifier) {
  case Modifier.PRIVATE:
   result = "private";
  case Modifier.PUBLIC:
   result = "public";
  case Modifier.PROTECTED:
   result = "protected";
  case Modifier.ABSTRACT:
   result = "abstract";
  case Modifier.FINAL:
   result = "final";
  case Modifier.NATIVE:
   result = "native";
  case Modifier.STATIC:
   result = "static";
  case Modifier.SYNCHRONIZED:
   result = "synchronized";
  case Modifier.STRICT:
   result = "strict";
  case Modifier.TRANSIENT:
   result = "transient";
  case Modifier.VOLATILE:
   result = "volatile";
  case Modifier.INTERFACE:
   result = "interface";
  }
  return result;
 }
 public static void printClassDefinition(Class clz) {
  String clzModifier = getModifier(clz.getModifiers());
  if (clzModifier != null && !clzModifier.equals("")) {
   clzModifier = clzModifier + " ";
  }
  String superClz = clz.getSuperclass().getName();
  if (superClz != null && !superClz.equals("")) {
   superClz = "extends " + superClz;
  }
  Class[] interfaces = clz.getInterfaces();
  String inters = "";
  for (int i = 0; i < interfaces.length; i++) {
   if (i == 0) {
    inters += "implements ";
   }
   inters += interfaces[i].getName();
  }
  System.out.println(clzModifier + clz.getName() + " " + superClz + " "
    + inters);
  System.out.println("{");
  Field[] fields = clz.getDeclaredFields();
  for (int i = 0; i < fields.length; i++) {
   String modifier = getModifier(fields[i].getModifiers());
   if (modifier != null && !modifier.equals("")) {
    modifier = modifier + " ";
   }
   String fieldName = fields[i].getName();
   String fieldType = fields[i].getType().getName();
   System.out.println("    " + modifier + fieldType + " " + fieldName
     + ";");
  }
  System.out.println();
  Method[] methods = clz.getDeclaredMethods();
  for (int i = 0; i < methods.length; i++) {
   Method method = methods[i];
   String modifier = getModifier(method.getModifiers());
   if (modifier != null && !modifier.equals("")) {
    modifier = modifier + " ";
   }
   String methodName = method.getName();
   Class returnClz = method.getReturnType();
   String retrunType = returnClz.getName();
   Class[] clzs = method.getParameterTypes();
   String paraList = "(";
   for (int j = 0; j < clzs.length; j++) {
    paraList += clzs[j].getName();
    if (j != clzs.length - 1) {
     paraList += ", ";
    }
   }
   paraList += ")";
   clzs = method.getExceptionTypes();
   String exceptions = "";
   for (int j = 0; j < clzs.length; j++) {
    if (j == 0) {
     exceptions += "throws ";
    }
    exceptions += clzs[j].getName();
    if (j != clzs.length - 1) {
     exceptions += ", ";
    }
   }
   exceptions += ";";
   String methodPrototype = modifier + retrunType + " " + methodName
     + paraList + exceptions;
   System.out.println("    " + methodPrototype);
  }
  System.out.println("}");
 }
}

실행 결과:

You can do something here before process your business
processing business.....
You can do something here after process your business
$Proxy0
$Proxy0 extends java.lang.reflect.Proxy implements com.fans.common.proxy.BusinessProcessor
{
    java.lang.reflect.Method m1;
    java.lang.reflect.Method m3;
    java.lang.reflect.Method m0;
    java.lang.reflect.Method m2;
    boolean equals(java.lang.Object);
    java.lang.String toString();
    int hashCode();
    void processBusiness();
}

BusinessProcessorHandler 클래스는 InvocationHandler 인터페이스의 호출 메서드를 구현합니다. 최종 프록시 호출 고정 인터페이스 메소드입니다.


분명히 Proxy.newProxyInstance 메서드는 다음 작업을 수행합니다.
1. 인터페이스에서 인터페이스를 구현하기 위해 전달된 두 번째 매개변수 인터페이스를 기반으로 클래스를 동적으로 생성합니다. 이 예에서는 BusinessProcessor 인터페이스의 processBusiness 메소드입니다. 그리고 Proxy 클래스를 상속하고 hashcode, toString 및 equals와 같은 세 가지 메서드를 다시 작성합니다. 구체적인 구현에 대해서는 다음을 참조하세요. ProxyGenerator.generateProxyClass(...); 이 예에서는 $Proxy0 클래스
2가 생성되고 새로 생성된 클래스는 전달된 첫 번째 매개변수인 classloder를 통해 jvm에 로드됩니다. $Proxy0 클래스 로드
3. 세 번째 매개변수를 사용하여 $Proxy0의 $Proxy0(InvocationHandler) 생성자를 호출하여 $Proxy0 개체를 생성하고, 인터페이스 매개변수를 사용하여 모든 해당 인터페이스의 메서드를 순회하고 메소드 객체 초기화 객체 여러 메소드 멤버 변수
4, $Proxy0 인스턴스를 클라이언트에 반환합니다.
지금은 괜찮아요. 클라이언트가 이를 어떻게 조정하는지 살펴보겠습니다. 그러면 명확해질 것입니다.
1. 클라이언트는 $Proxy0의 인스턴스 객체를 가져옵니다. $Proxy0은 BusinessProcessor를 상속하므로 BusinessProcessor로 변환하는 데 문제가 없습니다.
BusinessProcessor bp = (BusinessProcessor)Proxy.newProxyInstance(....);
2. bp.processBusiness();
실제로 호출되는 것은 $Proxy0.processBusiness()이고 $Proxy0.processBusiness입니다. ()의 구현은 InvocationHandler를 통해 호출 메소드를 호출하는 것입니다!

위는 Java 동적 프록시 적용에 대한 자세한 설명입니다. 자세한 내용은 PHP 중국어 웹사이트(www. php.cn)!


성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 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를 무료로 생성하십시오.

뜨거운 도구

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

Atom Editor Mac 버전 다운로드

Atom Editor Mac 버전 다운로드

가장 인기 있는 오픈 소스 편집기

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

SublimeText3 Mac 버전

SublimeText3 Mac 버전

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

DVWA

DVWA

DVWA(Damn Vulnerable Web App)는 매우 취약한 PHP/MySQL 웹 애플리케이션입니다. 주요 목표는 보안 전문가가 법적 환경에서 자신의 기술과 도구를 테스트하고, 웹 개발자가 웹 응용 프로그램 보안 프로세스를 더 잘 이해할 수 있도록 돕고, 교사/학생이 교실 환경 웹 응용 프로그램에서 가르치고 배울 수 있도록 돕는 것입니다. 보안. DVWA의 목표는 다양한 난이도의 간단하고 간단한 인터페이스를 통해 가장 일반적인 웹 취약점 중 일부를 연습하는 것입니다. 이 소프트웨어는