iis服务器助手广告广告
返回顶部
首页 > 资讯 > 前端开发 > VUE >类代理的方式有哪些
  • 638
分享到

类代理的方式有哪些

2024-04-02 19:04:59 638人浏览 安东尼
摘要

这篇文章主要讲解了“类代理的方式有哪些”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“类代理的方式有哪些”吧! 五种类代理的方式我们先定义出一个接口

这篇文章主要讲解了“类代理的方式有哪些”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“类代理的方式有哪些”吧!

 五种类代理的方式

我们先定义出一个接口和相应的实现类,方便后续使用代理类在方法中添加输出信息。

「定义接口」

public interface IUserapi {      String queryUserInfo();  }

「实现接口」

public class UserApi implements IUserApi {      public String queryUserInfo() {         return "沉淀、分享、成长,让自己和他人都能有所收获!";     }  }

好!接下来我们就给这个类方法使用代理加入一行额外输出的信息。

0. 先补充一点反射的知识

@Test public void test_reflect() throws Exception {     Class<UserApi> clazz = UserApi.class;     Method queryUserInfo = clazz.getMethod("queryUserInfo");     Object invoke = queryUserInfo.invoke(clazz.newInstance());     System.out.println(invoke); }
  • 点评:有代理地方几乎就会有反射,他们是一套互相配合使用的功能类。在反射中可以调用方法、获取属性、拿到注解等相关内容。这些都可以与接下来的类代理组合使用,完成各种框架中的技术场景。

1. JDK代理方式

public class jdkProxy {      public static <T> T getProxy(Class clazz) throws Exception {         ClassLoader classLoader = Thread.currentThread().getContextClassLoader();         return (T) Proxy.newProxyInstance(classLoader, new Class[]{clazz}, new InvocationHandler() {             public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {                 System.out.println(method.getName() + " 你被代理了,By JDKProxy!");                 return "沉淀、分享、成长,让自己和他人都能有所收获!";             }         });     }  }  @Test public void test_JDKProxy() throws Exception {     IUserApi userApi = JDKProxy.getProxy(IUserApi.class);     String invoke = userApi.queryUserInfo();     logger.info("测试结果:{}", invoke); }  
  • 指数:⭐⭐

  • 场景:中间件开发设计模式中代理模式和装饰器模式应用

  • 点评:这种JDK自带的类代理方式是非常常用的一种,也是非常简单的一种。基本会在一些中间件代码里看到例如:数据库路由组件、Redis组件等,同时我们也可以使用这样的方式应用到设计模式中。

2. CGLIB代理方式

public class CglibProxy implements MethodInterceptor {     public Object newInstall(Object object) {         return Enhancer.create(object.getClass(), this);     }     public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {         System.out.println("我被CglibProxy代理了");         return methodProxy.invokeSuper(o, objects);     } }  @Test public void test_CglibProxy() throws Exception {     CglibProxy cglibProxy = new CglibProxy();     UserApi userApi = (UserApi) cglibProxy.newInstall(new UserApi());     String invoke = userApi.queryUserInfo();     logger.info("测试结果:{}", invoke); }  
  • 场景:springaop切面、鉴权服务、中间件开发、rpc框架等

  • 点评:CGLIB不同于JDK,它的底层使用ASM字节码框架在类中修改指令码实现代理,所以这种代理方式也就不需要像JDK那样需要接口才能代理。同时得益于字节码框架的使用,所以这种代理方式也会比使用JDK代理的方式快1.5~2.0倍。

3. ASM代理方式

public class ASMProxy extends ClassLoader {      public static <T> T getProxy(Class clazz) throws Exception {          ClassReader classReader = new ClassReader(clazz.getName());         ClassWriter classWriter = new ClassWriter(classReader, ClassWriter.COMPUTE_MAXS);          classReader.accept(new ClassVisitor(ASM5, classWriter) {             @Override             public MethodVisitor visitMethod(int access, final String name, String descriptor, String signature, String[] exceptions) {                  // 方法过滤                 if (!"queryUserInfo".equals(name))                     return super.visitMethod(access, name, descriptor, signature, exceptions);                  final MethodVisitor methodVisitor = super.visitMethod(access, name, descriptor, signature, exceptions);                  return new AdviceAdapter(ASM5, methodVisitor, access, name, descriptor) {                      @Override                     protected void onMethodEnter() {                         // 执行指令;获取静态属性                         methodVisitor.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");                         // 加载常量 load constant                         methodVisitor.visitLdcInsn(name + " 你被代理了,By ASM!");                         // 调用方法                         methodVisitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);                         super.onMethodEnter();                     }                 };             }         }, ClassReader.EXPAND_FRAMES);          byte[] bytes = classWriter.toByteArray();          return (T) new ASMProxy().defineClass(clazz.getName(), bytes, 0, bytes.length).newInstance();     }  }  @Test public void test_ASMProxy() throws Exception {     IUserApi userApi = ASMProxy.getProxy(UserApi.class);     String invoke = userApi.queryUserInfo();     logger.info("测试结果:{}", invoke); }  
  • 场景:全链路监控、破解工具包、CGLIB、Spring获取类元数据等

  • 点评:这种代理就是使用字节码编程的方式进行处理,它的实现方式相对复杂,而且需要了解Java虚拟机规范相关的知识。因为你的每一步代理操作,都是在操作字节码指令,例如:Opcodes.GETSTATIC、Opcodes.INVOKEVIRTUAL,除了这些还有小200个常用的指令。但这种最接近底层的方式,也是最快的方式。所以在一些使用字节码插装的全链路监控中,会非常常见。

4. Byte-Buddy代理方式

public class ByteBuddyProxy {      public static <T> T getProxy(Class clazz) throws Exception {          DynamicType.Unloaded<?> dynamicType = new ByteBuddy()                 .subclass(clazz)                 .method(ElementMatchers.<MethodDescription>named("queryUserInfo"))                 .intercept(MethodDelegation.to(InvocationHandler.class))                 .make();          return (T) dynamicType.load(Thread.currentThread().getContextClassLoader()).getLoaded().newInstance();     }  }  @RuntimeType public static Object intercept(@Origin Method method, @AllArguments Object[] args, @SuperCall Callable<?> callable) throws Exception {     System.out.println(method.getName() + " 你被代理了,By Byte-Buddy!");     return callable.call(); }  @Test public void test_ByteBuddyProxy() throws Exception {     IUserApi userApi = ByteBuddyProxy.getProxy(UserApi.class);     String invoke = userApi.queryUserInfo();     logger.info("测试结果:{}", invoke); }  
  • 场景:AOP切面、类代理、组件、监控、日志

  • 点评:Byte Buddy 也是一个字节码操作的类库,但 Byte Buddy 的使用方式更加简单。无需理解字节码指令,即可使用简单的 API 就能很容易操作字节码,控制类和方法。比起JDK动态代理、cglib,Byte Buddy在性能上具有一定的优势。「另外」,2015年10月,Byte Buddy被 oracle 授予了 Duke's Choice大奖。该奖项对Byte Buddy的“ Java技术方面的巨大创新 ”表示赞赏。

5. Javassist代理方式

public class JavassistProxy extends ClassLoader {      public static <T> T getProxy(Class clazz) throws Exception {          ClassPool pool = ClassPool.getDefault();         // 获取类         CtClass ctClass = pool.get(clazz.getName());         // 获取方法         CtMethod ctMethod = ctClass.getDeclaredMethod("queryUserInfo");         // 方法前加强         ctMethod.insertBefore("{System.out.println(\"" + ctMethod.getName() + " 你被代理了,By Javassist\");}");          byte[] bytes = ctClass.toBytecode();          return (T) new JavassistProxy().defineClass(clazz.getName(), bytes, 0, bytes.length).newInstance();     }  }  @Test public void test_JavassistProxy() throws Exception {     IUserApi userApi = JavassistProxy.getProxy(UserApi.class)     String invoke = userApi.queryUserInfo();     logger.info("测试结果:{}", invoke); }  
  • 场景:全链路监控、类代理、AOP

  • 点评:Javassist 是一个使用非常广的字节码插装框架,几乎一大部分非入侵的全链路监控都是会选择使用这个框架。因为它不想ASM那样操作字节码导致风险,同时它的功能也非常齐全。另外,这个框架即可使用它所提供的方式直接编写插装代码,也可以使用字节码指令进行控制生成代码,所以综合来看也是一个非常不错的字节码框架。

感谢各位的阅读,以上就是“类代理的方式有哪些”的内容了,经过本文的学习后,相信大家对类代理的方式有哪些这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是编程网,小编将为大家推送更多相关知识点的文章,欢迎关注!

--结束END--

本文标题: 类代理的方式有哪些

本文链接: https://www.lsjlt.com/news/84433.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 类代理的方式有哪些
    这篇文章主要讲解了“类代理的方式有哪些”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“类代理的方式有哪些”吧! 五种类代理的方式我们先定义出一个接口...
    99+
    2024-04-02
  • java代理的方式有哪些
    Java代理有以下几种方式: 静态代理:在代理类中直接引用被代理类的对象,通过代理类对被代理类的方法进行调用和控制。 动态代...
    99+
    2024-03-07
    java
  • java中代理模式有哪些分类
    java中代理模式有哪些分类?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。java基本数据类型有哪些Java的基本数据类型分为:1、整数类型,用来表示整数的数据类型。2、浮...
    99+
    2023-06-14
  • 获取代理ip的方式有哪些
    本篇内容主要讲解“获取代理ip的方式有哪些”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“获取代理ip的方式有哪些”吧!1、用程序扫描代理ip地址。你可以去百度搜索“HTTP代理”,可以找到很多免...
    99+
    2023-06-25
  • Java动态代理的方式有哪些
    这篇文章主要介绍“Java动态代理的方式有哪些”,在日常操作中,相信很多人在Java动态代理的方式有哪些问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java动态代理的方式有哪些”的疑惑有所帮助!接下来,请跟...
    99+
    2023-06-26
  • 代理ip的配置方式有哪些
    这篇文章主要介绍“代理ip的配置方式有哪些”,在日常操作中,相信很多人在代理ip的配置方式有哪些问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”代理ip的配置方式有哪些”的疑惑有所帮助!接下来,请跟着小编一起来...
    99+
    2023-06-20
  • React开启代理的方式有哪些
    本篇内容介绍了“React开启代理的方式有哪些”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!开启代理的两种方式react并没有封装好了的aj...
    99+
    2023-06-20
  • http代理有哪些访问方式
    这篇文章主要讲解了“http代理有哪些访问方式”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“http代理有哪些访问方式”吧!一些朋友可能经常听到http代理的消息,但他们对它的了解很少。事实...
    99+
    2023-06-20
  • Java实现AOP代理的方式有哪些
    这篇文章主要介绍了Java实现AOP代理的方式有哪些的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Java实现AOP代理的方式有哪些文章都会有所收获,下面我们一起来看看吧。AOP是一种设计思想,是软件设计领域中...
    99+
    2023-07-02
  • 代码管理工作流的方式有哪些
    这篇文章主要讲解了“代码管理工作流的方式有哪些”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“代码管理工作流的方式有哪些”吧! 集中式工作流集中式工作流这种工作方式对于使用过SVN的...
    99+
    2023-06-15
  • Java动态代理常用方式有哪些
    本篇内容介绍了“Java动态代理常用方式有哪些”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!什么是动态代理?动态代理就是,在程序运行期,创建...
    99+
    2023-06-25
  • php代替curl的方式有哪些
    PHP中有多种替代cURL的方式,包括:1. file_get_contents()函数:可以用来从URL中读取文件的内容,可以通过...
    99+
    2023-09-06
    PHP
  • 代理服务器IP代理有哪些分类
    这篇文章主要讲解了“代理服务器IP代理有哪些分类”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“代理服务器IP代理有哪些分类”吧!IP代理有哪些类型?HTTP代理HTTP代理就是让网民通过代理...
    99+
    2023-06-20
  • 服务器分类的方式有哪些
    根据不同的标准和功能,服务器可以分为以下几类:1. 按照用途分类:Web服务器、数据库服务器、邮件服务器、文件服务器、应用服务器等。...
    99+
    2023-06-06
    服务器分类 服务器
  • java中有哪些代理模式
    java中有哪些代理模式?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。Java的特点有哪些Java的特点有哪些1.Java语言作为静态面向对象编程语言的代表,实现了面向对象...
    99+
    2023-06-14
  • 代理服务器有哪些类型
    代理服务器有哪些类型,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。代理服务器(ProxyServer)作为服务器安全的一项重要功能,其工作主要集中于开放系统互连...
    99+
    2023-06-25
  • 在线代理ip有哪些类型
    这篇文章主要讲解了“在线代理ip有哪些类型”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“在线代理ip有哪些类型”吧!1、按时效划分。可以根据代理ip的生存期、有效期或生存期,把它们分为短效代...
    99+
    2023-06-25
  • javascript代码的使用方式有哪些
    这篇文章给大家分享的是有关javascript代码的使用方式有哪些的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。javascript代码有两种使用方式,分别是:1、直接执行,打开一个网页时,所有定义在script...
    99+
    2023-06-15
  • 调试Node.js代码的方式有哪些
    这篇文章主要讲解了“调试Node.js代码的方式有哪些”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“调试Node.js代码的方式有哪些”吧!很多时候,我苦恼于 Node.js 的调试,只会使...
    99+
    2023-06-21
  • 常见的HashMap迭代方式有哪些
    这篇文章主要介绍了常见的HashMap迭代方式有哪些的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇常见的HashMap迭代方式有哪些文章都会有所收获,下面我们一起来看看吧。一、 HashMap介绍HashMap...
    99+
    2023-06-27
软考高级职称资格查询
推荐阅读
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作