千家信息网

Java如何实现动态代理

发表于:2026-10-31 作者:千家信息网编辑
千家信息网最后更新 2026年10月31日,小编给大家分享一下Java如何实现动态代理,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!Java 动态代理准备:maven
千家信息网最后更新 2026年10月31日Java如何实现动态代理

小编给大家分享一下Java如何实现动态代理,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!

Java 动态代理

准备:maven依赖

              cglib        cglib        3.2.5                javassist        javassist        3.12.1.GA              junit      junit      3.8.1      test      
1,jdk方式实现

jdk方式的动态代理需要通过实现接口来实现,因此,先创建一个简单的接口及实现类:

接口:

package per.ym.proxy.jdk;public interface BookStore {    String add(String bookName);    String delete(String bookName);}

实现类:

package per.ym.proxy.jdk;public class BookStoreImpl implements BookStore {    public String add(String bookName) {        System.out.println("增加书籍:" + bookName);        return bookName;    }    public String delete(String bookName) {        System.out.println("删除书籍:" + bookName);        return bookName;    }}

创建代理类工厂:

package per.ym.proxy.jdk;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;public class BookStoreJdkProxyFactory implements InvocationHandler{    private BookStore bookStroe;    public BookStoreJdkProxyFactory(BookStore bookStore) {        this.bookStroe = bookStore;    }    public BookStore getProxy() {        return (BookStore) Proxy.newProxyInstance(bookStroe.getClass().getClassLoader(),                bookStroe.getClass().getInterfaces(), this);    }    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {        System.out.println("调用方法:" + method.getName());        String bookName = (String) method.invoke(bookStroe, args);        System.out.println("方法:" + method.getName() + " 执行完成");        return bookName;    }}

测试类:

package per.ym.proxy.jdk;public class TestMain {    public static void main(String[] args) {         //将生成的代理类保存到文件中        System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");        BookStoreJdkProxyFactory factory = new BookStoreJdkProxyFactory(new BookStoreImpl());        BookStore proxy = factory.getProxy();        proxy.add("thinking in java");        proxy.delete("spring in action");    }}

测试结果:

调用方法:add增加书籍:thinking in java方法:add 执行完成调用方法:delete删除书籍:spring in action方法:delete 执行完成

工程目录下生成代理类文件:

反编译生成的代理类(避免篇幅过大,删除了equals,toString,hashCode方法):

package com.sun.proxy;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;import java.lang.reflect.UndeclaredThrowableException;import per.ym.proxy.jdk.BookStore;public final class $Proxy0  extends Proxy  implements BookStore{  private static Method m1;  private static Method m2;  private static Method m3;  private static Method m4;  private static Method m0;  public $Proxy0(InvocationHandler paramInvocationHandler)  {    super(paramInvocationHandler);  }  public final String add(String paramString)  {    try    {      return (String)this.h.invoke(this, m3, new Object[] { paramString });    }    catch (Error|RuntimeException localError)    {      throw localError;    }    catch (Throwable localThrowable)    {      throw new UndeclaredThrowableException(localThrowable);    }  }  public final String delete(String paramString)  {    try    {      return (String)this.h.invoke(this, m4, new Object[] { paramString });    }    catch (Error|RuntimeException localError)    {      throw localError;    }    catch (Throwable localThrowable)    {      throw new UndeclaredThrowableException(localThrowable);    }  }  static  {    try    {      m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[] { Class.forName("java.lang.Object") });      m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]);      m3 = Class.forName("per.ym.proxy.jdk.BookStore").getMethod("add", new Class[] { Class.forName("java.lang.String") });      m4 = Class.forName("per.ym.proxy.jdk.BookStore").getMethod("delete", new Class[] { Class.forName("java.lang.String") });      m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]);      return;    }    catch (NoSuchMethodException localNoSuchMethodException)    {      throw new NoSuchMethodError(localNoSuchMethodException.getMessage());    }    catch (ClassNotFoundException localClassNotFoundException)    {      throw new NoClassDefFoundError(localClassNotFoundException.getMessage());    }  }}

从以上得,代理类实现了被代理类的接口(因此使用jdk实现的动态代理需要被代理类实现接口),并持有传入的InvocationHandler,当调用代理类的方法时,都会转到InvocationHandler的invoke方法中,并传入自身,被调用方法及参数。

2,Cglib方式实现

Cglib是基于继承实现的代理,因此,被代理类不需要实现,直接使用一个类即可:

被代理类:

package per.ym.proxy.cglib;public class BookStore {    public String add(String bookName) {        System.out.println("增加书籍:" + bookName);        return bookName;    }    public String delete(String bookName) {        System.out.println("删除书籍:" + bookName);        return bookName;    }}

创建代理类工厂:

package per.ym.proxy.cglib;import net.sf.cglib.proxy.Enhancer;import net.sf.cglib.proxy.MethodInterceptor;import net.sf.cglib.proxy.MethodProxy;import java.lang.reflect.Method;public class BookStoreCglibProxyFactory implements MethodInterceptor {    private BookStore bookStore;    public BookStoreCglibProxyFactory(BookStore bookStore) {        this.bookStore = bookStore;    }    public BookStore getProxy() {        Enhancer enhancer = new Enhancer();        //设置父类        enhancer.setSuperclass(bookStore.getClass());        //回调方法        enhancer.setCallback(this);        //创建代理        return (BookStore) enhancer.create();    }    public Object intercept(Object obj, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {        System.out.println("调用方法:" + method.getName());        String bookName = (String) methodProxy.invokeSuper(obj, args);        System.out.println("方法:" + method.getName() + " 执行完成");        return bookName;    }}

测试类:

package per.ym.proxy.cglib;import net.sf.cglib.core.DebuggingClassWriter;public class TestMain {    public static void main(String[] args) {        //将生成的代理类保存到指定目录下        System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "D:\\proxy_test");        BookStoreCglibProxyFactory factory = new BookStoreCglibProxyFactory(new BookStore());        BookStore proxy = factory.getProxy();        proxy.add("thinking in java");        proxy.delete("spring in action");    }}

测试结果:

CGLIB debugging enabled, writing to 'D:\proxy_test'调用方法:add增加书籍:thinking in java方法:add 执行完成调用方法:delete删除书籍:spring in action方法:delete 执行完成

指定目录下生成的代理类class文件:

反编译生成的代理类(删除了一些注释的东西):

package per.ym.proxy.cglib;import java.lang.reflect.Method;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 BookStore$$EnhancerByCGLIB$$847c411a  extends BookStore  implements Factory{  private boolean CGLIB$BOUND;  public static Object CGLIB$FACTORY_DATA;  private static final ThreadLocal CGLIB$THREAD_CALLBACKS;  private static final Callback[] CGLIB$STATIC_CALLBACKS;  private MethodInterceptor CGLIB$CALLBACK_0;  private static Object CGLIB$CALLBACK_FILTER;  private static final Method CGLIB$add$0$Method;  private static final MethodProxy CGLIB$add$0$Proxy;  private static final Object[] CGLIB$emptyArgs;  private static final Method CGLIB$delete$1$Method;  private static final MethodProxy CGLIB$delete$1$Proxy;  private static final Method CGLIB$equals$2$Method;  private static final MethodProxy CGLIB$equals$2$Proxy;  private static final Method CGLIB$toString$3$Method;  private static final MethodProxy CGLIB$toString$3$Proxy;  private static final Method CGLIB$hashCode$4$Method;  private static final MethodProxy CGLIB$hashCode$4$Proxy;  private static final Method CGLIB$clone$5$Method;  private static final MethodProxy CGLIB$clone$5$Proxy;  final String CGLIB$add$0(String paramString)  {    return super.add(paramString);  }  public final String add(String paramString)  {    MethodInterceptor tmp4_1 = this.CGLIB$CALLBACK_0;    if (tmp4_1 == null)    {      tmp4_1;      CGLIB$BIND_CALLBACKS(this);    }    MethodInterceptor tmp17_14 = this.CGLIB$CALLBACK_0;    if (tmp17_14 != null) {      return (String)tmp17_14.intercept(this, CGLIB$add$0$Method, new Object[] { paramString }, CGLIB$add$0$Proxy);    }    return super.add(paramString);  }  final String CGLIB$delete$1(String paramString)  {    return super.delete(paramString);  }  public final String delete(String paramString)  {    MethodInterceptor tmp4_1 = this.CGLIB$CALLBACK_0;    if (tmp4_1 == null)    {      tmp4_1;      CGLIB$BIND_CALLBACKS(this);    }    MethodInterceptor tmp17_14 = this.CGLIB$CALLBACK_0;    if (tmp17_14 != null) {      return (String)tmp17_14.intercept(this, CGLIB$delete$1$Method, new Object[] { paramString }, CGLIB$delete$1$Proxy);    }    return super.delete(paramString);  }  final boolean CGLIB$equals$2(Object paramObject)  {    return super.equals(paramObject);  }  public final boolean equals(Object paramObject)  {    MethodInterceptor tmp4_1 = this.CGLIB$CALLBACK_0;    if (tmp4_1 == null)    {      tmp4_1;      CGLIB$BIND_CALLBACKS(this);    }    MethodInterceptor tmp17_14 = this.CGLIB$CALLBACK_0;    if (tmp17_14 != null)    {      Object tmp41_36 = tmp17_14.intercept(this, CGLIB$equals$2$Method, new Object[] { paramObject }, CGLIB$equals$2$Proxy);      tmp41_36;      return tmp41_36 == null ? false : ((Boolean)tmp41_36).booleanValue();    }    return super.equals(paramObject);  }  final String CGLIB$toString$3()  {    return super.toString();  }  public final String toString()  {    MethodInterceptor tmp4_1 = this.CGLIB$CALLBACK_0;    if (tmp4_1 == null)    {      tmp4_1;      CGLIB$BIND_CALLBACKS(this);    }    MethodInterceptor tmp17_14 = this.CGLIB$CALLBACK_0;    if (tmp17_14 != null) {      return (String)tmp17_14.intercept(this, CGLIB$toString$3$Method, CGLIB$emptyArgs, CGLIB$toString$3$Proxy);    }    return super.toString();  }  final int CGLIB$hashCode$4()  {    return super.hashCode();  }  public final int hashCode()  {    MethodInterceptor tmp4_1 = this.CGLIB$CALLBACK_0;    if (tmp4_1 == null)    {      tmp4_1;      CGLIB$BIND_CALLBACKS(this);    }    MethodInterceptor tmp17_14 = this.CGLIB$CALLBACK_0;    if (tmp17_14 != null)    {      Object tmp36_31 = tmp17_14.intercept(this, CGLIB$hashCode$4$Method, CGLIB$emptyArgs, CGLIB$hashCode$4$Proxy);      tmp36_31;      return tmp36_31 == null ? 0 : ((Number)tmp36_31).intValue();    }    return super.hashCode();  }  final Object CGLIB$clone$5()    throws CloneNotSupportedException  {    return super.clone();  }  protected final Object clone()    throws CloneNotSupportedException  {    MethodInterceptor tmp4_1 = this.CGLIB$CALLBACK_0;    if (tmp4_1 == null)    {      tmp4_1;      CGLIB$BIND_CALLBACKS(this);    }    MethodInterceptor tmp17_14 = this.CGLIB$CALLBACK_0;    if (tmp17_14 != null) {      return tmp17_14.intercept(this, CGLIB$clone$5$Method, CGLIB$emptyArgs, CGLIB$clone$5$Proxy);    }    return super.clone();  }  public BookStore$$EnhancerByCGLIB$$847c411a()  {    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)  {    847c411a local847c411a = (847c411a)paramObject;    if (!local847c411a.CGLIB$BOUND)    {      local847c411a.CGLIB$BOUND = true;      Object tmp23_20 = CGLIB$THREAD_CALLBACKS.get();      if (tmp23_20 == null)      {        tmp23_20;        CGLIB$STATIC_CALLBACKS;      }      local847c411a.CGLIB$CALLBACK_0 = (tmp31_28 == null ? tmp31_28 : (MethodInterceptor)((Callback[])tmp23_20)[0]);    }  }  public Object newInstance(Callback[] paramArrayOfCallback)  {    CGLIB$SET_THREAD_CALLBACKS(paramArrayOfCallback);    CGLIB$SET_THREAD_CALLBACKS(null);    return new 847c411a();  }  public Object newInstance(Callback paramCallback)  {    CGLIB$SET_THREAD_CALLBACKS(new Callback[] { paramCallback });    CGLIB$SET_THREAD_CALLBACKS(null);    return new 847c411a();  }  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 {}}

这个看着就有点难受了,而且还生成了其他的class文件,不过能够看出来生成的代理类是通过继承被代理类实现的,当调用指定方法时会转到回调方法中,并传入自身,被调用方法,方法参数和一个MethodProxy,这个MethodProxy还没仔细去看是什么,不过猜测应该是封装了被调用方法相关的信息,最终也是通过反射调用被代理对象的相应方法,如果猜错了,不负责。

3,Javassist方式实现

javassist可以动态的生成一个class,关于它的更多信息,请到这里去:https://www.jianshu.com/p/43424242846b

被代理类:

package per.ym.proxy.javassist;public class BookStore {    public String add(String bookName) {        System.out.println("增加书籍:" + bookName);        return bookName;    }    public String delete(String bookName) {        System.out.println("删除书籍:" + bookName);        return bookName;    }}

创建代理类工厂:

package per.ym.proxy.javassist;import java.lang.reflect.Method;import javassist.ClassPool;import javassist.CtClass;import javassist.CtField;import javassist.CtNewMethod;public class BookStoreJavassistProxyFactory {    public static BookStore getProxy() throws Exception {        ClassPool classPool = ClassPool.getDefault();        //代理类名        String proxyClassName = BookStore.class.getName() + "Proxy";        //创建代理类        CtClass ctClass = classPool.makeClass(proxyClassName);        //设置父类为BookStore        ctClass.setSuperclass(classPool.get(BookStore.class.getName()));        //添加属性bookStore        ctClass.addField(CtField.make("private " + BookStore.class.getName() + " bookStore = new " +                BookStore.class.getName() + "();", ctClass));        //保存整个方法信息        StringBuilder methodSb = new StringBuilder();        //保存方法参数信息        StringBuilder paraSb1 = new StringBuilder();        //保存调用被代理类方法的参数信息        StringBuilder paraSb2 = new StringBuilder();        //保存异常信息        StringBuilder exceptionSb = new StringBuilder();        Method[] methods = BookStore.class.getDeclaredMethods();        for (Method m : methods) {            if (m.getModifiers() == 2) {                 continue;            }            methodSb.append(getModifier(m.getModifiers())).append(" ")                    .append(m.getReturnType().getName()).append(" ")                    .append(m.getName());           Class[] clazzs = m.getParameterTypes();           paraSb1.append("(");           paraSb2.append("(");           for (int i=0 ; i< clazzs.length ; i++) {               if (paraSb1.length() > 1) {                   paraSb1.append(",").append(clazzs[i].getName()).append(" ").append("arg" + i);                   paraSb2.append(",").append("arg" + i);               } else {                   paraSb1.append(clazzs[i].getName()).append(" ").append("arg" + i);                   paraSb2.append("arg" + i);               }           }           paraSb1.append(")");           paraSb2.append(")");           methodSb.append(paraSb1);           clazzs = m.getExceptionTypes();           if (clazzs.length > 0) {               methodSb.append(" throws ");               for (int i=0; i < clazzs.length; i++) {                   if (exceptionSb.length() > 0) {                       exceptionSb.append(",").append(clazzs[i].getName());                   } else {                       exceptionSb.append(clazzs[i].getName());                   }               }           }           methodSb.append("{")                   .append("System.out.println(\"执行方法:" + m.getName() + "\"" + ");")                   .append(m.getReturnType().getName() + " result = bookStore." + m.getName() + paraSb2 + ";")                   .append("System.out.println(\"方法:" + m.getName() + " 执行完成  \");")                   .append("return result;")                   .append("}");           //添加方法到生成的代理类中           ctClass.addMethod(CtNewMethod.make(methodSb.toString(), ctClass));           methodSb.delete(0, methodSb.length());           paraSb1.delete(0, paraSb1.length());           paraSb2.delete(0, paraSb2.length());           exceptionSb.delete(0, exceptionSb.length());        }        //保存生成的class信息到文件中        ctClass.writeFile();        //获取代理类class对象        Class clazz = ctClass.toClass();        return clazz.newInstance();    }    private static String getModifier(int modifier) {        switch(modifier) {            case 0:                return "protected";            case 1:                return "public";            case 2:                return "private";            case 4:                return "";            default:                return "public";        }    }}

测试类:

package per.ym.proxy.javassist;public class TestMain {    public static void main(String[] args) throws Exception {        BookStore proxy = BookStoreJavassistProxyFactory.getProxy();        proxy.add("thinking in java");        proxy.delete("spring in action");    }}

测试结果:

执行方法:add增加书籍:thinking in java方法:add 执行完成  执行方法:delete删除书籍:spring in action方法:delete 执行完成

生成的代理类class文件:

反编译生成的代理类(格式化后的):

package per.ym.proxy.javassist;import java.io.PrintStream;public class BookStoreProxy  extends BookStore{  private BookStore bookStore = new BookStore();  public String add(String paramString)  {    System.out.println("执行方法: add");    String str = this.bookStore.add(paramString);    System.out.println("方法: add 执行完成  ");    return str;  }  public String delete(String paramString)  {    System.out.println("执行方法:delete");    String str = this.bookStore.delete(paramString);    System.out.println("方法:delete 执行完成 ");    return str;  }}

不知道为啥方法参数名是paramString,而不是我设置的arg0?

以上是"Java如何实现动态代理"这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注行业资讯频道!

方法 代理 生成 书籍 信息 动态 文件 测试 参数 接口 方式 工厂 目录 篇文章 结果 编译 内容 对象 更多 难受 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 互联网是第几次科技革命的成果 华服互联网科技怎么样 疫情对互联网科技公司影响 美国互联网科技巨头监管 深圳科技互联网 互联网科技论文 丰台科技园 互联网 互联网高科技企业 深圳市运趣互联网科技有限公司 农村开互联网科技讲堂 互联网教育科技公司vipkid 互联网金融科技公司干啥的 威龙国际互联网科技公司 科技赋能视角下互联网保险发展 互联网第三次科技革命特征 城市宝互联网科技有限公司 济南小医互联网科技有限公司招聘 互联网界的黑科技 好易买互联网科技 山东亿川互联网科技有限责任公司 喔噻互联网科技有限公司 苏州找大状互联网科技有限公司 互联网科技小贷 以房互联网科技 致聘互联网科技 天扬科技互联网广告 太原新华互联网科技学校怎么样 山东吉时兔互联网科技有限公司 阿里巴巴算科技企业还是互联网 武汉健翔互联网络科技有限公司
0