JDK动态代理生成class文件和cglib动态代理生成class文件

反编译软件

概述

  • JDK动态代理:其代理对象必须是某个接口的实现,它是通过在运行期期间创建一个接口的实现类来完成对目标对象的代理。
  • CGLIB代理:实现原理类似于JDK动态代理,只是它在运行期间生成的代理对象是针对目标类扩展的子类。CGLIB是高效的代码生成包,底层依靠ASM(开源的Java字节码编辑类库)操作字节码实现。

1 JDK动态代理

1.1 创建代理过程:

  1. 定义接口
  2. 实现接口
  3. 定义代理类,继承InvocationHandler接口

1.2 具体代码

接口:

public interface Person {
    void say();
}

实现类:

public class JdkStudent implements Person{
    @Override
    public void say() {
        System.out.println("我是学生...");
    }
}

代理类:

public class JdkProxy implements InvocationHandler{

    private Object target;

    public JdkProxy() {
        super();
    }

    public JdkProxy(Object target) {
        this.target = target;
    }
    /**
     该方法负责集中处理动态代理类上的所有方法调用。
     第一个参数既是代理类实例,
     第二个参数是被调用的方法对象
     第三个方法是调用参数。
     调用处理器根据这三个参数进行预处理或分派到委托类实例上发射执行
    */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        System.out.println("------插入前置通知代码-------------");  
        Object obj = method.invoke(target, args);
        System.out.println("------插入后置通知代码-------------");  
        return obj;
    }
}

测试:

public class JdkTest {
    public static void main(String[] args) {
         //生成$Proxy0的class文件 System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");
        JdkStudent student = new JdkStudent();
        Person p = (Person) Proxy.newProxyInstance(student.getClass().getClassLoader(),
                student.getClass().getInterfaces(), new JdkProxy(student));
        System.out.println(p);
        p.say();
    }
}

注:JDK动态代理生成的文件默认在sun/proxy下,如果没有该目录会报Exception in thread “main” java.lang.InternalError: I/O exception saving generated file: java.io.FileNotFoundException: sun\proxy$Proxy0.class (系统找不到指定的路径。)

生成的代理class

package sun.proxy;

import com.gz.design.proxy.jdk.Person;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;

public final class $Proxy0
  extends Proxy
  implements Person
{
  private static Method m3;
  private static Method m1;
  private static Method m0;
  private static Method m2;

  public $Proxy0(InvocationHandler paramInvocationHandler)
  {
    super(paramInvocationHandler);
  }

  public final void say()
  {
    try
    {
      this.h.invoke(this, m3, null);
      return;
    }
    catch (Error|RuntimeException localError)
    {
      throw localError;
    }
    catch (Throwable localThrowable)
    {
      throw new UndeclaredThrowableException(localThrowable);
    }
  }

  public final boolean equals(Object paramObject)
  {
    try
    {
      return ((Boolean)this.h.invoke(this, m1, new Object[] { paramObject })).booleanValue();
    }
    catch (Error|RuntimeException localError)
    {
      throw localError;
    }
    catch (Throwable localThrowable)
    {
      throw new UndeclaredThrowableException(localThrowable);
    }
  }

  public final int hashCode()
  {
    try
    {
      return ((Integer)this.h.invoke(this, m0, null)).intValue();
    }
    catch (Error|RuntimeException localError)
    {
      throw localError;
    }
    catch (Throwable localThrowable)
    {
      throw new UndeclaredThrowableException(localThrowable);
    }
  }

  public final String toString()
  {
    try
    {
      return (String)this.h.invoke(this, m2, null);
    }
    catch (Error|RuntimeException localError)
    {
      throw localError;
    }
    catch (Throwable localThrowable)
    {
      throw new UndeclaredThrowableException(localThrowable);
    }
  }

  static
  {
    try
    {
      m3 = Class.forName("com.gz.design.proxy.jdk.Person").getMethod("say", new Class[0]);
      m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[] { Class.forName("java.lang.Object") });
      m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]);
      m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]);
      return;
    }
    catch (NoSuchMethodException localNoSuchMethodException)
    {
      throw new NoSuchMethodError(localNoSuchMethodException.getMessage());
    }
    catch (ClassNotFoundException localClassNotFoundException)
    {
      throw new NoClassDefFoundError(localClassNotFoundException.getMessage());
    }
  }
}

2 cglib动态代理

1.1 创建代理过程:

  1. 创建Enhancer对象
  2. 用Enhancer对象设置代理类的父类(被代理类)
  3. 创建回调对象(回调类实现 MethodInterceptor 接口)
  4. 用Enhancer对象设置回调对象
  5. 用Enhancer对象创建代理对象

1.2 具体代码

目标类:

`

public class Student{
public void say() {
System.out.println(“我是学生…”);
test();
}

public void test() {
    System.out.println("test");
}

}


**代理类:**

public class CglibProxy implements MethodInterceptor{

 /** 
 * 重写方法拦截在方法前和方法后加入业务 
 * Object obj为目标对象 
 * Method method为目标方法 
 * Object[] params 为参数, 
 * MethodProxy proxy CGlib方法代理对象 
 */  
@Override
public Object intercept(Object obj, Method method, Object[] args,
        MethodProxy methodProxy) throws Throwable {
    System.out.println("===============");
    return methodProxy.invokeSuper(obj, args);
}

}

**测试类:**

public class CglibProxyTest {

public static void main(String[] args) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
// 生成class类的路径
    System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "E://tmp");   
    Enhancer enhancer = new Enhancer();
    enhancer.setSuperclass(Student.class);
    enhancer.setCallback(new CglibProxy());

    Student student = (Student) enhancer.create();
    student.say();
    }
 }

**生成的代理class**

package com.gz.design.proxy.cglib;

import java.lang.reflect.Method;
import net.sf.cglib.core.ReflectUtils;
import net.sf.cglib.proxy.Callback;
import net.sf.cglib.proxy.Factory;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

public class Student

E n h a n c e r B y C G L I B
4b734e7
extends Student
implements Factory
{
private boolean CGLIB B O U N D ; p r i v a t e s t a t i c f i n a l T h r e a d L o c a l C G L I B THREAD_CALLBACKS;
private static final Callback[] CGLIB S T A T I C C A L L B A C K S ; p r i v a t e M e t h o d I n t e r c e p t o r C G L I B CALLBACK_0;
private static final Method CGLIB s a y 0 M e t h o d ; p r i v a t e s t a t i c f i n a l M e t h o d P r o x y C G L I B say 0 Proxy;
private static final Object[] CGLIB e m p t y A r g s ; p r i v a t e s t a t i c f i n a l M e t h o d C G L I B finalize 1 Method;
private static final MethodProxy CGLIB f i n a l i z e 1 P r o x y ; p r i v a t e s t a t i c f i n a l M e t h o d C G L I B equals 2 Method;
private static final MethodProxy CGLIB e q u a l s 2 P r o x y ; p r i v a t e s t a t i c f i n a l M e t h o d C G L I B toString 3 Method;
private static final MethodProxy CGLIB t o S t r i n g 3 P r o x y ; p r i v a t e s t a t i c f i n a l M e t h o d C G L I B hashCode 4 Method;
private static final MethodProxy CGLIB h a s h C o d e 4 P r o x y ; p r i v a t e s t a t i c f i n a l M e t h o d C G L I B clone 5 Method;
private static final MethodProxy CGLIB c l o n e 5$Proxy;

static void CGLIB STATICHOOK1()    {      CGLIB THREAD_CALLBACKS = new ThreadLocal();
CGLIB e m p t y A r g s = n e w O b j e c t [ 0 ] ; C l a s s l o c a l C l a s s 1 = C l a s s . f o r N a m e ( c o m . g z . d e s i g n . p r o x y . c g l i b . S t u d e n t E n h a n c e r B y C G L I B 4 b 734 e 7 ) ; C l a s s l o c a l C l a s s 2 ; M e t h o d [ ] t m p 50 4 7 = R e f l e c t U t i l s . f i n d M e t h o d s ( n e w S t r i n g [ ] s a y , ( ) V , ( l o c a l C l a s s 2 = C l a s s . f o r N a m e ( c o m . g z . d e s i g n . p r o x y . c g l i b . S t u d e n t ) ) . g e t D e c l a r e d M e t h o d s ( ) ) ; C G L I B say 0 Method = tmp50_47[0];
CGLIB s a y 0 P r o x y = M e t h o d P r o x y . c r e a t e ( l o c a l C l a s s 2 , l o c a l C l a s s 1 , " ( ) V " , " s a y " , " C G L I B say 0 ) ; t m p 50 4 7 ; M e t h o d [ ] t m p 143 1 40 = R e f l e c t U t i l s . f i n d M e t h o d s ( n e w S t r i n g [ ] f i n a l i z e , ( ) V , e q u a l s , ( L j a v a / l a n g / O b j e c t ; ) Z , t o S t r i n g , ( ) L j a v a / l a n g / S t r i n g ; , h a s h C o d e , ( ) I , c l o n e , ( ) L j a v a / l a n g / O b j e c t ; , ( l o c a l C l a s s 2 = C l a s s . f o r N a m e ( j a v a . l a n g . O b j e c t ) ) . g e t D e c l a r e d M e t h o d s ( ) ) ; C G L I B finalize 1 Method = tmp143_140[0];
CGLIB f i n a l i z e 1 P r o x y = M e t h o d P r o x y . c r e a t e ( l o c a l C l a s s 2 , l o c a l C l a s s 1 , " ( ) V " , " f i n a l i z e " , " C G L I B finalize 1 ) ; M e t h o d [ ] t m p 163 1 43 = t m p 143 1 40 ; C G L I B equals 2 Method = tmp163_143[1];
CGLIB e q u a l s 2 P r o x y = M e t h o d P r o x y . c r e a t e ( l o c a l C l a s s 2 , l o c a l C l a s s 1 , " ( L j a v a / l a n g / O b j e c t ; ) Z " , " e q u a l s " , " C G L I B equals 2 ) ; M e t h o d [ ] t m p 183 1 63 = t m p 163 1 43 ; C G L I B toString 3 Method = tmp183_163[2];
CGLIB t o S t r i n g 3 P r o x y = M e t h o d P r o x y . c r e a t e ( l o c a l C l a s s 2 , l o c a l C l a s s 1 , " ( ) L j a v a / l a n g / S t r i n g ; " , " t o S t r i n g " , " C G L I B toString 3 ) ; M e t h o d [ ] t m p 203 1 83 = t m p 183 1 63 ; C G L I B hashCode 4 Method = tmp203_183[3];
CGLIB h a s h C o d e 4 P r o x y = M e t h o d P r o x y . c r e a t e ( l o c a l C l a s s 2 , l o c a l C l a s s 1 , " ( ) I " , " h a s h C o d e " , " C G L I B hashCode 4 ) ; M e t h o d [ ] t m p 223 2 03 = t m p 203 1 83 ; C G L I B clone 5 Method = tmp223_203[4];
CGLIB c l o n e 5 P r o x y = M e t h o d P r o x y . c r e a t e ( l o c a l C l a s s 2 , l o c a l C l a s s 1 , " ( ) L j a v a / l a n g / O b j e c t ; " , " c l o n e " , " C G L I B clone$5”);
tmp223_203;
return;
}

final void CGLIB s a y 0()
{
super.say();
}

public final void say()
{
MethodInterceptor tmp4_1 = this.CGLIB C A L L B A C K 0 ; i f ( t m p 4 1 == n u l l ) t m p 4 1 ; C G L I B $ B I N D C A L L B A C K S ( t h i s ) ; i f ( t h i s . C G L I B CALLBACK_0 != null) {
return;
}
super.say();
}

final void CGLIB f i n a l i z e 1()
throws Throwable
{
super.finalize();
}

protected final void finalize()
throws Throwable
{
MethodInterceptor tmp4_1 = this.CGLIB C A L L B A C K 0 ; i f ( t m p 4 1 == n u l l ) t m p 4 1 ; C G L I B $ B I N D C A L L B A C K S ( t h i s ) ; i f ( t h i s . C G L I B CALLBACK_0 != null) {
return;
}
super.finalize();
}

final boolean CGLIB e q u a l s 2(Object paramObject)
{
return super.equals(paramObject);
}

public final boolean equals(Object paramObject)
{
MethodInterceptor tmp4_1 = this.CGLIB C A L L B A C K 0 ; i f ( t m p 4 1 == n u l l ) t m p 4 1 ; C G L I B $ B I N D C A L L B A C K S ( t h i s ) ; M e t h o d I n t e r c e p t o r t m p 17 1 4 = t h i s . C G L I B CALLBACK_0;
if (tmp17_14 != null)
{
Object tmp41_36 = tmp17_14.intercept(this, CGLIB e q u a l s 2 M e t h o d , n e w O b j e c t [ ] p a r a m O b j e c t , C G L I B equals 2 Proxy);
tmp41_36;
return tmp41_36 == null ? false : ((Boolean)tmp41_36).booleanValue();
}
return super.equals(paramObject);
}

final String CGLIB t o S t r i n g 3()
{
return super.toString();
}

public final String toString()
{
MethodInterceptor tmp4_1 = this.CGLIB C A L L B A C K 0 ; i f ( t m p 4 1 == n u l l ) t m p 4 1 ; C G L I B $ B I N D C A L L B A C K S ( t h i s ) ; M e t h o d I n t e r c e p t o r t m p 17 1 4 = t h i s . C G L I B CALLBACK_0;
if (tmp17_14 != null) {
return (String)tmp17_14.intercept(this, CGLIB t o S t r i n g 3 M e t h o d , C G L I B emptyArgs, CGLIB t o S t r i n g 3$Proxy);
}
return super.toString();
}

final int CGLIB h a s h C o d e 4()
{
return super.hashCode();
}

public final int hashCode()
{
MethodInterceptor tmp4_1 = this.CGLIB C A L L B A C K 0 ; i f ( t m p 4 1 == n u l l ) t m p 4 1 ; C G L I B $ B I N D C A L L B A C K S ( t h i s ) ; M e t h o d I n t e r c e p t o r t m p 17 1 4 = t h i s . C G L I B CALLBACK_0;
if (tmp17_14 != null)
{
Object tmp36_31 = tmp17_14.intercept(this, CGLIB h a s h C o d e 4 M e t h o d , C G L I B emptyArgs, CGLIB h a s h C o d e 4$Proxy);
tmp36_31;
return tmp36_31 == null ? 0 : ((Number)tmp36_31).intValue();
}
return super.hashCode();
}

final Object CGLIB c l o n e 5()
throws CloneNotSupportedException
{
return super.clone();
}

protected final Object clone()
throws CloneNotSupportedException
{
MethodInterceptor tmp4_1 = this.CGLIB C A L L B A C K 0 ; i f ( t m p 4 1 == n u l l ) t m p 4 1 ; C G L I B $ B I N D C A L L B A C K S ( t h i s ) ; M e t h o d I n t e r c e p t o r t m p 17 1 4 = t h i s . C G L I B CALLBACK_0;
if (tmp17_14 != null) {
return tmp17_14.intercept(this, CGLIB c l o n e 5 M e t h o d , C G L I B emptyArgs, CGLIB c l o n e 5$Proxy);
}
return super.clone();
}

/* Error */
public static MethodProxy CGLIB findMethodProxy(net.sf.cglib.core.Signature arg0)    {      // Byte code:      //   0: aload_0      //   1: invokevirtual 128   java/lang/Object:toString   ()Ljava/lang/String;      //   4: dup      //   5: invokevirtual 129   java/lang/Object:hashCode   ()I      //   8: lookupswitch    default:+132->140, -1574182249:+60->68, -909388886:+72->80, -508378822:+84->92, 1826985398:+96->104, 1913648695:+108->116, 1984935277:+120->128      //   68: ldc -125      //   70: invokevirtual 132  java/lang/Object:equals (Ljava/lang/Object;)Z      //   73: ifeq +68 -> 141      //   76: getstatic 64   com/gz/design/proxy/cglib/Student E n h a n c e r B y C G L I B 4 b 734 e 7 : C G L I B finalize 1 Proxy Lnet/sf/cglib/proxy/MethodProxy;
// 79: areturn
// 80: ldc -122
// 82: invokevirtual 132 java/lang/Object:equals (Ljava/lang/Object;)Z
// 85: ifeq +56 -> 141
// 88: getstatic 46 com/gz/design/proxy/cglib/Student

E n h a n c e r B y C G L I B
4b734e7:CGLIB s a y 0 P r o x y L n e t / s f / c g l i b / p r o x y / M e t h o d P r o x y ; / / 91 : a r e t u r n / / 92 : l d c 120 / / 94 : i n v o k e v i r t u a l 132 j a v a / l a n g / O b j e c t : e q u a l s ( L j a v a / l a n g / O b j e c t ; ) Z / / 97 : i f e q + 44 > 141 / / 100 : g e t s t a t i c 125 c o m / g z / d e s i g n / p r o x y / c g l i b / S t u d e n t E n h a n c e r B y C G L I B 4 b 734 e 7 : C G L I B clone 5 Proxy Lnet/sf/cglib/proxy/MethodProxy;
// 103: areturn
// 104: ldc -118
// 106: invokevirtual 132 java/lang/Object:equals (Ljava/lang/Object;)Z
// 109: ifeq +32 -> 141
// 112: getstatic 77 com/gz/design/proxy/cglib/Student
E n h a n c e r B y C G L I B
4b734e7:CGLIB e q u a l s 2 P r o x y L n e t / s f / c g l i b / p r o x y / M e t h o d P r o x y ; / / 115 : a r e t u r n / / 116 : l d c 116 / / 118 : i n v o k e v i r t u a l 132 j a v a / l a n g / O b j e c t : e q u a l s ( L j a v a / l a n g / O b j e c t ; ) Z / / 121 : i f e q + 20 > 141 / / 124 : g e t s t a t i c 94 c o m / g z / d e s i g n / p r o x y / c g l i b / S t u d e n t E n h a n c e r B y C G L I B 4 b 734 e 7 : C G L I B toString 3 Proxy Lnet/sf/cglib/proxy/MethodProxy;
// 127: areturn
// 128: ldc -114
// 130: invokevirtual 132 java/lang/Object:equals (Ljava/lang/Object;)Z
// 133: ifeq +8 -> 141
// 136: getstatic 107 com/gz/design/proxy/cglib/Student
E n h a n c e r B y C G L I B
4b734e7:CGLIB h a s h C o d e 4$Proxy Lnet/sf/cglib/proxy/MethodProxy;
// 139: areturn
// 140: pop
// 141: aconst_null
// 142: areturn
}

public Student

E n h a n c e r B y C G L I B
4b734e7()
{
CGLIB$BIND_CALLBACKS(this);
}

public static void CGLIB SET_THREAD_CALLBACKS(Callback[] paramArrayOfCallback)    {      CGLIB THREAD_CALLBACKS.set(paramArrayOfCallback);
}

public static void CGLIB SET_STATIC_CALLBACKS(Callback[] paramArrayOfCallback)    {      CGLIB STATIC_CALLBACKS = paramArrayOfCallback;
}

private static final void CGLIB BIND_CALLBACKS(Object paramObject)    {      4b734e7 local4b734e7 = (4b734e7)paramObject;      if (!local4b734e7.CGLIB BOUND)
{
local4b734e7.CGLIB B O U N D = t r u e ; O b j e c t t m p 23 2 0 = C G L I B THREAD_CALLBACKS.get();
if (tmp23_20 == null)
{
tmp23_20;
CGLIB STATIC_CALLBACKS;        }        local4b734e7.CGLIB CALLBACK_0 = (tmp31_28 == null ? tmp31_28 : (MethodInterceptor)((Callback[])tmp23_20)[0]);
}
}

public Object newInstance(Callback[] paramArrayOfCallback)
{
CGLIB S E T T H R E A D C A L L B A C K S ( p a r a m A r r a y O f C a l l b a c k ) ; C G L I B SET_THREAD_CALLBACKS(null);
return new 4b734e7();
}

public Object newInstance(Callback paramCallback)
{
CGLIB S E T T H R E A D C A L L B A C K S ( n e w C a l l b a c k [ ] p a r a m C a l l b a c k ) ; C G L I B SET_THREAD_CALLBACKS(null);
return new 4b734e7();
}

/* Error */
public Object newInstance(Class[] arg1, Object[] arg2, Callback[] arg3)
{
// Byte code:
// 0: aload_3
// 1: invokestatic 206 com/gz/design/proxy/cglib/Student

E n h a n c e r B y C G L I B
4b734e7:CGLIB S E T T H R E A D C A L L B A C K S ( [ L n e t / s f / c g l i b / p r o x y / C a l l b a c k ; ) V / / 4 : n e w 2 c o m / g z / d e s i g n / p r o x y / c g l i b / S t u d e n t E n h a n c e r B y C G L I B 4 b 734 e 7 / / 7 : d u p / / 8 : a l o a d 1 / / 9 : d u p / / 10 : a r r a y l e n g t h / / 11 : t a b l e s w i t c h d e f a u l t : + 24 > 35 , 0 : + 17 > 28 / / 28 : p o p / / 29 : i n v o k e s p e c i a l 207 c o m / g z / d e s i g n / p r o x y / c g l i b / S t u d e n t E n h a n c e r B y C G L I B 4 b 734 e 7 : ( ) V / / 32 : g o t o + 17 > 49 / / 35 : g o t o + 3 > 38 / / 38 : p o p / / 39 : n e w 213 j a v a / l a n g / I l l e g a l A r g u m e n t E x c e p t i o n / / 42 : d u p / / 43 : l d c 41 / / 45 : i n v o k e s p e c i a l 218 j a v a / l a n g / I l l e g a l A r g u m e n t E x c e p t i o n : ( L j a v a / l a n g / S t r i n g ; ) V / / 48 : a t h r o w / / 49 : a c o n s t n u l l / / 50 : i n v o k e s t a t i c 206 c o m / g z / d e s i g n / p r o x y / c g l i b / S t u d e n t E n h a n c e r B y C G L I B 4 b 734 e 7 : C G L I B SET_THREAD_CALLBACKS ([Lnet/sf/cglib/proxy/Callback;)V
// 53: areturn
}

public Callback getCallback(int paramInt)
{
CGLIB$BIND_CALLBACKS(this);
switch (paramInt)
{
case 0:
break;
}
return null;
}

public void setCallback(int paramInt, Callback paramCallback)
{
switch (paramInt)
{
case 0:
this.CGLIB$CALLBACK_0 = ((MethodInterceptor)paramCallback);
break;
}
}

public Callback[] getCallbacks()
{
CGLIB BIND_CALLBACKS(this);      return new Callback[] { this.CGLIB CALLBACK_0 };
}

public void setCallbacks(Callback[] paramArrayOfCallback)
{
this.CGLIB$CALLBACK_0 = ((MethodInterceptor)paramArrayOfCallback[0]);
}

static {}
}

“`

动态代理资料一
动态代理资料二

猜你喜欢

转载自blog.csdn.net/u010811939/article/details/80763336
今日推荐