在上一篇文章中,我讨论了基于标准Java的代理对象。 当您要在实现接口的对象上具有方法调用处理程序时,可以使用这些方法。 Java反射代理的创建要求您具有一个实现接口的对象。 我们要代理的对象已经失控,它没有实现我们要从处理程序调用的接口,而我们仍然希望拥有代理。

什么时候需要不带接口的对象的代理?

这是很常见的情况。 如果有的话,我们有一个JPA实现,例如Hibernate,它实现了记录的延迟加载。 例如,审核日志记录存储在一个表中,并且每个记录(第一个记录除外)都引用了上一项。 就像是

class LinkedAuditLogRecord {LinkedAuditLogRecord previous;AuditLogRecord actualRecord;
}

通过JPA加载记录将返回一个对象LinkedAuditLogRecord ,该对象包含以前的记录作为对象,依此类推,直到第一个在名为previos的字段中可能为null记录为止。 (这不是实际的代码。)任何JPA实现从一开始就抓取并加载整个表到我们感兴趣的记录都是一个非常糟糕的实现。 相反,持久层仅加载实际记录,并创建一个扩展LinkedAuditLogRecord的代理对象,而这就是previous字段的内容。 实际字段通常是私有字段,如果我们的代码尝试访问上一条记录,则代理对象将在该时间加载它。 简而言之,这是延迟加载。

但是,JPA实现如何为未实现接口的类的对象创建代理? Java反射代理实现无法做到这一点,因此JPA实现使用了不同的东西。 他们通常使用的是cglib。

什么是cglib

Cglib是一个开放源代码库,能够在Java运行时创建和加载内存中的类文件。 为此,它使用Java字节码生成库'asm',这是一个非常低级的字节码创建工具。 我不会在本文中深入探讨。

如何使用cglib

使用cglib创建代理对象几乎与使用JDK反射代理API一样简单。 我使用cglib创建了与上周文章相同的代码:

package proxy;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 CglibProxyDemo {static class Original {public void originalMethod(String s) {System.out.println(s);}}static class Handler implements MethodInterceptor {private final Original original;public Handler(Original original) {this.original = original;}public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {System.out.println("BEFORE");method.invoke(original, args);System.out.println("AFTER");return null;}}public static void main(String[] args){Original original = new Original();MethodInterceptor handler = new Handler(original);Original f = (Original) Enhancer.create(Original.class,handler);f.originalMethod("Hallo");}
}

区别在于类的名称略有不同,并且我们没有接口。

代理类扩展原始类也很重要,因此在创建代理对象时,它将调用原始类的构造函数。 如果这是资源匮乏的话,我们可能会有一些问题。 但是,这是我们不能回避的事情。 如果我们想为一个已经存在的类提供一个代理对象,那么我们应该有一个接口,或者我们必须扩展原始类,否则我们就不能使用代理对象代替原始类。

翻译自: https://www.javacodegeeks.com/2016/01/creating-proxy-object-using-cglib.html

使用cglib创建代理对象相关推荐

  1. cglib创建代理对象(1)

    cglib创建代理对象 还是从一个的小demo开始 例子 被代理的类 public class Bean{public String sayHello(String name) {return &qu ...

  2. Spring AOP 源码分析 - 创建代理对象

    1.简介 在上一篇文章中,我分析了 Spring 是如何为目标 bean 筛选合适的通知器的.现在通知器选好了,接下来就要通过代理的方式将通知器(Advisor)所持有的通知(Advice)织入到 b ...

  3. 使用djcproxy创建代理对象

    在过去的几周中,我展示了如何使用Java Reflection API和cglib创建代理对象. 在本文中,我将向您展示如何使用djcproxy做到这一点. 哦,不是,另一个代理实现! 除了我创建此代 ...

  4. Spring AOP源码(2)—AspectJAwareAdvisorAutoProxyCreator创建代理对象【两万字】

      基于最新Spring 5.x,介绍了Spring AOP中的AspectJAwareAdvisorAutoProxyCreator自动代理创建者的工作流程,对于创建代理对象的源码进行了深度分析! ...

  5. CGLIb 创建代理

    CGLIb 创建代理 创建回调 创建代理(通过增强器和回调接口) 设置回调 CGLib总结 代理对象通过继承目标对象来封装目标对象的实现 CGlib 拦截的实现--在执行目标方法前判断拦截器是否存在并 ...

  6. CGLIB动态代理对象执行流程分析

    前言 都说CGLIB动态代理对象执行方法的速度相较于JDK动态代理更快,那么为什么更快,实际是因为CGLIB中采用了FastClass机制,本篇文章将对CGLIB动态代理对象执行某一个方法的流程进行分 ...

  7. 【设计模式】代理模式 ( 动态代理使用流程 | 创建目标对象 | 创建被代理对象 | 创建调用处理程序 | 动态创建代理对象 | 动态代理调用 )

    文章目录 前言 一.静态代理的弊端 二.动态代理的优势 三.动态代理使用流程 1.目标对象接口 2.被代理对象 3.调用处理程序 4.客户端 四.动态生成 代理对象 类 的 字节码 文件数据 前言 代 ...

  8. MyBatis运行原理(三)接口式编程及创建代理对象原理分析

    一.面向接口开发步骤 定义代理接口,将操作数据库的方法定义在代理接口中. 在SQL 映射文件中编写SQL 语句. 将SQL 映射文件注册在MyBatis 的全局配置文件中. 编写测试代码. 二.环境准 ...

  9. CGLIB 实现代理对象API

    转载自 CGLIB 实现代理对象API 1. 加入库 cglib库 cglib-2.2.jar asm库(cglib 需要asm库,如果没有加入asm的jar文件,就会报asm错误) asm-3.1. ...

最新文章

  1. 刷了三遍面试题仍拿不到offer?如何掌握AI技术面正确刷题姿势?
  2. waitpid最后以一个参数设为0_西门子MM440变频器参数设置
  3. Linux图形界面与命令行模式切换
  4. phing用户手册第四章Getting Started译文
  5. c++各类型有效范围
  6. 福建农商银行计算机类笔试题目,2020年福建福州农商银行免笔试面试试题
  7. 1000道Python题库系列分享十一(9道)
  8. sed命令在文件头部插入文本---BSD和GNU版本通用写法
  9. python工资一般多少西安-Python让我在西安成为高薪quot;贵族”
  10. 用ffmpeg快速剪切和合并视频
  11. 9.1.4 前端 - HTML body标签 - 标题,段落,分割线,换行,特殊符号,列表,超链接,图片,div/span,表格,表单,input标签,多行文本,单选/多选,下拉,按钮...
  12. 数据结构课程设计———迷宫和哈夫曼编/译码器
  13. PageRank算法(Dead ends、Spider Traps问题)
  14. VS Code、IDEA开发工具及插件
  15. 阿里云智能编码插件Cosy,提升开发效率杠杠滴!
  16. 手机端自适应表格table样式如何写
  17. 活久见!西电毕设门处理结果:只让肇事者延毕一年、取消保研
  18. P3386二分图最大匹配模版
  19. MatLab专用变量
  20. 计算机中的进制 进制转换 位运算符号

热门文章

  1. 并发场景下MySQL存在的问题及解决思路
  2. 单例模式懒汉、饿汉和登记
  3. avue中怎样隐藏新增和编辑的按钮
  4. 2020蓝桥杯省赛---java---B---6(分类计数)
  5. JAVA注解和反射(笔记)
  6. Android增加自定义监听事件
  7. php打印 二维数组,PHP中遍历二维数组_以不同形式的输出操作实例
  8. 指令寻址方式与数据寻址方式
  9. 近似装箱问题(两种脱机算法实现)
  10. Spring Boot错误–创建在类路径资源DataSourceAutoConfiguration中定义的名称为“ dataSource”的bean时出错...