java JDKダイナミックエージェント分析(java.lang.reflect.Proxy)


java JDKダイナミックエージェント分析(java.lang.reflect.Proxy)

/** 
 * JDK        (java.lang.reflect.Proxy  ) 
 * 
 * @author     
 * 
 */ 
public class ProxyStudy { 
   
  @SuppressWarnings("unchecked") 
  public static void main(String[] args) throws Exception { 
    //      :        ,        
    // getProxyClass()       java.lang.Class   ,              。 
    Class clazzProxy = Proxy.getProxyClass(Collection.class.getClassLoader(), Collection.class); 
    System.out.println("        :" + clazzProxy.getName()); 
    System.out.println("----------             ---------"); 
    Constructor[] constructors = clazzProxy.getConstructors(); 
    int i = 1; 
    for (Constructor constructor : constructors) { 
      System.out.println(" " + (i++) + "      :" + constructor.getName()); 
      Class[] parameterClazz = constructor.getParameterTypes(); 
      System.out.println(" " + (i++) + "       :" + Arrays.asList(parameterClazz)); 
    } 
    System.out.println("----------             ---------"); 
    Method[] methods = clazzProxy.getDeclaredMethods(); 
    for (int j = 0; j < methods.length; j++) { 
      Method method = methods[j]; 
      System.out.println(" " + (j + 1) + "      :" + method.getName()); 
      Class[] parameterClazz = method.getParameterTypes(); 
      System.out.println(" " + (j + 1) + "       :" + Arrays.asList(parameterClazz)); 
    } 
    System.out.println("---------             ---------"); 
    //                     java.lang.reflect.InvocationHandler     ,      
    // clazzProxy.newInstance();      ,               
    // InvocationHandler                   。 
    Constructor constructor = clazzProxy.getConstructor(InvocationHandler.class); 
 
    //         
    Collection proxyBuildCollection = (Collection) constructor 
        .newInstance(new InvocationHandler() { 
          //        ArrayList      ? 
          //      constructor clazzProxy          ,clazzProxy   Proxy.getProxyClass()     , 
          //         ,         ,             ,          Collection 
          //  ArrayList   Collection  ,              
          ArrayList target = new ArrayList();//          
 
          public Object invoke(Object proxy, Method method, 
              Object[] args) throws Throwable { 
            System.out.println("    " + method.getName() + "    :" 
                + System.currentTimeMillis()); 
            Object result = method.invoke(target, args);//                      
            System.out.println("    " + method.getName() + "    :" 
                + System.currentTimeMillis()); 
            return result; 
          } 
 
        }); 
    proxyBuildCollection.clear(); 
    proxyBuildCollection.add("abc"); 
    proxyBuildCollection.add("dbc"); 
    System.out.println(proxyBuildCollection.size()); 
    System.out.println(proxyBuildCollection.getClass().getName()); 
     
    /** 
     *     :    : 
     * 1,  Proxy.getProxyClass(classLoader,interface)          class   (clazz) 
     *   getProxyClass()       :              ,              (       JDK              ) 
     *   
     * 2,         clazz            constructor,       constructor newInstance()              
     *   constructor newInstance()           InvocationHandler    handler,            A   invoke   
     *      A              ,   invoke        A         。 
     *      :        ProxyObject x   ――――>          handler invoke   ――――> invoke    handler  target   
     *       x  (    target                  )        。(        P ,  target     P ,    P        ) 
     *   
     *       x      ?   Object         toString,hashCode,equals       handler ,         handler   
     *     proxyBuildCollection.getClass().getName()     handler getClass  ,        
     *   
     * 3, handler invoke   return method.invoke(target,args)       target   。           ,  ,             , 
     *                  args,            
     */ 
    System.out.println("-------------------        --------------------"); 
     
    // proxyBuildColl  ArrayList     
    Collection proxyBuildCollection2 = (Collection) Proxy.newProxyInstance( 
        Collection.class.getClassLoader(),//        
        new Class[] { Collection.class },//             
        //   handler 
        new InvocationHandler() { 
          ArrayList target = new ArrayList(); 
 
          public Object invoke(Object proxy, Method method, 
              Object[] args) throws Throwable { 
            System.out.println(method.getName() + "    ..."); 
            if (null != args) { 
              System.out.println("     :" + Arrays.asList(args)); 
            } else { 
              System.out.println("     :" + null); 
            } 
            Object result = method.invoke(target, args); 
            System.out.println(method.getName() + "    ..."); 
            return result; 
          } 
        }); 
    proxyBuildCollection2.add("abc"); 
    proxyBuildCollection2.size(); 
    proxyBuildCollection2.clear(); 
    proxyBuildCollection2.getClass().getName(); 
     
    System.out.println("------------------- JDK       --------------------"); 
    Set proxySet = (Set) buildProxy(new HashSet(), new MyAdvice()); 
    proxySet.add("abc"); 
    proxySet.size(); 
  } 
  /** 
   *               
   * 
   * @param target 
   *          (        ) 
   * @return 
   */ 
  public static Object buildProxy(final Object target,final AdviceInter advice) { 
    Object proxyObject = Proxy.newProxyInstance( 
        target.getClass().getClassLoader(),//        
        target.getClass().getInterfaces(), //             
        // handler 
        new InvocationHandler() { 
           
          public Object invoke(Object proxy, Method method, 
              Object[] args) throws Throwable { 
            advice.beforeMethod(target, method, args); 
            Object result = method.invoke(target, args); 
            advice.afterMethod(target, method, args); 
            return result; 
          } 
        }); 
    return proxyObject; 
  } 
   
} 
 

/** 
 *                       
 * 
 * @author     
 * 
 */ 
public class MyAdvice implements AdviceInter { 
 
  public void afterMethod(Object target, Method method, Object[] args) { 
    System.out.println("     :" + target.getClass().getName()); 
    System.out.println(method.getName() + "    !"); 
  } 
 
  public void beforeMethod(Object target, Method method, Object[] args) { 
    System.out.println(method.getName() + "    "); 
    if (null != args) { 
      System.out.println("   :" + Arrays.asList(args)); 
    } else { 
      System.out.println("   :" + null); 
    } 
  } 
} 

/** 
 *                  
 * 
 * @author     
 * 
 */ 
public interface AdviceInter { 
  /** 
   *          
   * 
   */ 
  public void beforeMethod(Object target, Method method, Object[] args); 
 
  /** 
   *          
   * 
   * @param target 
   *           
   * @param method 
   *         
   * @param args 
   *         
   */ 
  public void afterMethod(Object target, Method method, Object[] args); 
}