동적 프록시는 실제로 지정한 모든 인터페이스를 기반으로 클래스를 동적으로 생성하는 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)!