Java 동적 에이전트의 응용 설명

7984 단어
동적 에이전트는 사실java입니다.lang.reflect.Proxy 클래스는 사용자가 지정한 모든 인터페이스에 따라class byte를 동적으로 생성합니다. 이class는Proxy 클래스를 계승하고 지정한 모든 인터페이스를 실현합니다. (파라미터에 전송된 인터페이스 그룹)그리고 지정한 classloader를 이용해서 class byte를 시스템에 불러옵니다. 마지막으로 이런 종류의 대상을 만들고, 이 대상의 일부 값을 초기화합니다. 예를 들어 invocation Handler, 즉 모든 인터페이스에 대응하는 Method 구성원입니다.초기화한 후 대상을 호출된 클라이언트에게 되돌려줍니다.이렇게 클라이언트가 받은 것은 모든 인터페이스를 실현하는 Proxy 대상입니다.인스턴스 분석을 보십시오.
 
  
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 인터페이스의 invoke 방법을 실현했다. 이 클래스는 Proxy가 최종적으로 고정 인터페이스를 호출하는 방법이다.
분명히 Proxy.new Proxy Instance 방법은 다음과 같은 몇 가지를 할 수 있다. 1. 전송된 두 번째 매개 변수인interfaces에 따라 하나의 클래스를 동적으로 생성하여interfaces의 인터페이스를 실현한다. 이 예에서 Business Processor 인터페이스의process 비즈니스 방법이다.또한 Proxy 클래스를 계승하고 해시코드, 토스트링, equals 등 세 가지 방법을 다시 썼다.ProxyGenerator를 참조하십시오.generateProxyClass(...); 이 예에서 $Proxy0 클래스 2가 생성되었습니다. 첫 번째 인자인classloder를 통해 생성된 클래스를 jvm에 불러옵니다.$Proxy0 클래스load3은 세 번째 인자를 이용하여 $Proxy0의 $Proxy0(InvocationHandler) 구조 함수를 호출하여 $Proxy0의 대상을 만들고 인터페이스의 모든 인터페이스를 인터페이스로 옮겨다니는 방법을 사용하며 Method 대상의 초기화 대상의 몇 개의 Method 구성원 변수4를 생성하여 $Proxy0의 실례를 클라이언트에게 되돌려줍니다.이제 됐어.우리는 클라이언트가 어떻게 조정하는지 다시 보면 분명히 알 수 있다.1, 클라이언트가 받은 것은 $Proxy0의 실례 대상입니다. $Proxy0은 비즈니스 Processor를 계승했기 때문에 비즈니스 Processor로 전환하는 데 아무런 문제가 없습니다.         BusinessProcessor bp = (BusinessProcessor)Proxy.newProxyInstance(....);    2,bp.processBusiness();실제로 호출된 것은 $Proxy0입니다.processBusiness();그러면 $Proxy0.프로세스 비즈니스 ()의 실현은 Invocation Handler를 통해 invoke 방법을 호출하는 것입니다!

좋은 웹페이지 즐겨찾기