Java CGLIB动态代理示例

2023-11-18

1. CGLIB动态代理简介

JDK动态代理是利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理。
而cglib动态代理是利用asm开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理。

2. JDK动态代理与CGLIB区别

JDK动态代理和CGLIB字节码生成的区别?

  1. JDK动态代理只能对实现了接口的类生成代理,而不能针对类
  2. CGLIB是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法。因为是继承,所以该类或方法最好不要声明成final
3.代码示例

注:需要引入相关jar包,下载cglib.jarasm.jar

1. 真实对象
package dynamicproxy.cglib;

/**
 * 真实对象
 * @author <u>sunlh</u>
 *
 */
public class HelloWorld { 
     public void sayHelloWorld() {
           System.out.println("Hello World!");
     }
}
2. 建立代理对象与真实服务对象的关系&实现代理逻辑方法
package dynamicproxy.cglib;

import java.lang.reflect.Method;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

public class CglibProxyExample implements MethodInterceptor{

     /**
      * 生成CGLIB代理对象
      * @param cls Class类
      * @return Class类的CGLIB代理对象
      */
     public Object getProxy(<u>Class</u> cls) {
           // CGLIB <u>enhancer</u>增强类对象
           Enhancer enhancer = new Enhancer();
           // 设置增强类型
           enhancer.setSuperclass(cls);
           // 定义代理逻辑对象为当前对象,要求当前对象实现MethodInterceptor方法
           enhancer.setCallback(this);
           // 生成并返回代理对象
           return enhancer.create();
     }   

     @Override
     public Object intercept(Object proxy, Method method, 
Object[] args, MethodProxy methodProxy) throws Throwable {
           System.out.println("调用真实对象前");
           // CGLIB反射调用真实对象方法
           Object result = methodProxy.invokeSuper(proxy, args);
           System.out.println("调用真实对象后");
           return result;
     }
}

这里使用CGLIB的加强者EnHancer,通过设置超类的方法(setSuperclass),然后通过setCallback方法设置哪个类为它的代理类。其中,参数为this就意味着是当前对象,那就要求用this这个对象实现接口MethodInterceptor的方法intercept,然后返回代理对象。
那么此时当前类的intercept方法就是其代理逻辑方法。

在反射真实对象前后进行打印,CGLIB通过如下方法完成

Object result = methodProxy.invokeSuper(proxy, args);
3. 测试CGLIB动态代理
package dynamicproxy.cglib;
/**
 * 测试
 * @author sunlh
 *
 */
public class TestCglibProxy {
	public static void main(String[] args) {
		CglibProxyExample cpe = new CglibProxyExample();
		HelloWorld proxy = (HelloWorld) cpe.getProxy(HelloWorld.class);
		proxy.sayHelloWorld("张三");
	}
}

控制台输出

调用真实对象前
Hello 张三
调用真实对象后
4.特殊情况

当真实对象声明为final时,使用CGLIB动态代理会报错

代码示例
修改真实对象,声明为final(即不可继承)

package dynamicproxy.cglib;
/**
 * 真实对象
 * @author <u>sunlh</u>
 *
 */
public final class HelloWorld {    

     public void sayHelloWorld(String name) {
           System.out.println("Hello " + name);
     }
}

再次执行测试方法,控制台输出
java.lang.IllegalArgumentException: Cannot subclass final class class dynamicproxy.cglib.HelloWorld

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java CGLIB动态代理示例 的相关文章

  • 如何将画廊意图中的“打开”更改为“完成”?

    我使用以下意图打开画廊来选择多个图像和视频 Intent intent new Intent intent setType image video intent putExtra Intent EXTRA ALLOW MULTIPLE tr
  • Spring Security 自定义过滤器

    我想自定义 Spring security 3 0 5 并将登录 URL 更改为 login 而不是 j spring security check 我需要做的是允许登录 目录并保护 admin report html 页面 首先 我使用教
  • 通过SOCKS代理连接Kafka

    我有一个在 AWS 上运行的 Kafka 集群 我想用标准连接到集群卡夫卡控制台消费者从我的应用程序服务器 应用程序服务器可以通过 SOCKS 代理访问互联网 无需身份验证 如何告诉 Kafka 客户端通过代理进行连接 我尝试了很多事情 包
  • “java.net.MalformedURLException:未找到协议”读取到 html 文件

    我收到一个错误 java net MalformedURLException Protocol not found 我想读取网络上的 HTML 文件 mainfest uses permission android name android
  • Spring Data JPA 选择不同

    我有一个情况 我需要建立一个select distinct a address from Person a 其中地址是 Person 内的地址实体 类型的查询 我正在使用规范动态构建我的 where 子句并使用findAll Specifi
  • 大数据使用什么数据结构

    我有一个包含一百万行的 Excel 工作表 每行有 100 列 每行代表一个具有 100 个属性的类的实例 列值是这些属性的值 哪种数据结构最适合在这里使用来存储数百万个数据实例 Thanks 这实际上取决于您需要如何访问这些数据以及您想要
  • Kotlin 未解决的参考:CLI 上 gradle 的 println

    放一个printlnkotlin 函数返回之前的语句会崩溃 堆栈跟踪 thufir dur NetBeansProjects kotlin thufir dur NetBeansProjects kotlin gradle clean bu
  • Spring Security SAML2 使用 G Suite 作为 Idp

    我正在尝试使用 Spring Security 5 3 3 RELEASE 来处理 Spring Boot 应用程序中的 SAML2 身份验证 Spring Boot 应用程序将成为 SP G Suite 将成为 IDP 在我的 Maven
  • 需要使用 joda 进行灵活的日期时间转换

    我想使用 joda 解析电子邮件中的日期时间字符串 不幸的是我得到了各种不同的格式 例如 Wed 19 Jan 2011 12 52 31 0600 Wed 19 Jan 2011 10 15 34 0800 PST Wed 19 Jan
  • 套接字的读写如何同步?

    我们创建一个套接字 在套接字的一侧有一个 服务器 在另一侧有一个 客户端 服务器和客户端都可以向套接字写入和读取 这是我的理解 我不明白以下事情 如果服务器从套接字读取数据 它在套接字中是否只看到客户端写入套接字的内容 我的意思是 如果服务
  • 如何在 Java 中创建接受多个值的单个注释

    我有一个名为 Retention RetentionPolicy SOURCE Target ElementType METHOD public interface JIRA The Key Bug number JIRA referenc
  • 返回 Java 8 中的通用函数接口

    我想写一种函数工厂 它应该是一个函数 以不同的策略作为参数调用一次 它应该返回一个函数 该函数根据参数选择其中一种策略 该参数将由谓词实现 嗯 最好看看condition3为了更好的理解 问题是 它没有编译 我认为因为编译器无法弄清楚函数式
  • “无法实例化活动”错误

    我的一个 Android 应用程序拥有大约 100 000 个用户 每周大约 10 次 我会通过 Google 的市场工具向我报告以下异常情况 java lang RuntimeException Unable to instantiate
  • Spring-ws:如何从没有“Request”元素的 xsd 创建 Wsdl

    尝试为客户端实现 SOAP Web 服务 我需要一个 wsdl 文件来通过soapUI 测试该服务 但正如您在下面看到的 这个 xsd 没有 Request 和 Response 方法 所有请求和响应都被定义为基本 ServiceProvi
  • Java Swing:需要一个高质量的带有复选框的开发 JTree

    我一直在寻找一个 Tree 实现 其中包含复选框 其中 当您选择一个节点时 树中的所有后继节点都会被自动选择 当您取消选择一个节点时 树中其所有后继节点都会自动取消选择 当已经选择了父节点 并且从其后继之一中删除了选择时 节点颜色将发生变化
  • 使用按钮作为列表的渲染器

    我想使用一个更复杂的渲染器 其中包含列表的多个组件 更准确地说 类似于this https stackoverflow com questions 10840498 java swing 1 6 textinput like firefox
  • Java中HashMap和ArrayList的区别?

    在爪哇 ArrayList and HashMap被用作集合 但我不明白我们应该在哪些情况下使用ArrayList以及使用时间HashMap 他们两者之间的主要区别是什么 您具体询问的是 ArrayList 和 HashMap 但我认为要完
  • 如何使用play框架上传多个文件?

    我在用play framework 2 1 2 使用java我正在创建视图来上传多个文件 我的代码在这里 form action routes upload up enctype gt multipart form data
  • org.apache.commons.net.io.CopyStreamException:复制时捕获 IOException

    我正在尝试使用以下方法中的代码将在我的服务器中创建的一些文件复制到 FTP 但奇怪的是我随机地低于错误 我无法弄清楚发生了什么 Exception org apache commons net io CopyStreamException
  • Java EE 目录结构

    我对以下教程有疑问 http www mkyong com jsf2 jsf 2 internationalization example http www mkyong com jsf2 jsf 2 internationalizatio

随机推荐

  • python使用字典暴力解析wifi密码

    前言 最近无wifi可用 搜到了很多高质量但是没有密码的WiFi 我在想应该可以用python调用常见的wifi字典包来暴力破解一下这些WiFi 也许可以成功 原理 使用pip install pywifi命令安装pywifi 在代码中设置
  • 基于Python3的接口自动化总结(一)——文件上传接口

    文件上传接口 api POST http host api import 接口入参 file 文件内容 import os import urllib3 import ast def import by rest self file pat
  • 原码,补码,反码的应用

    原码 补码 反码的应用 计算机专业的同学应该知道 课本中对原码反码补码的介绍大致是这样的几句话 正数 正数的原码是他的本身 正数的反码还是等于原码 正数的补码等于他的原码 负数 负数的原码等于该数值的二进制 最高位表示符号位 正数取0 负数
  • 微众银行马智涛:解放数据生产力,以金融科技助力数字经济发展|数字思考者50人...

    钛媒体2022特别专题策划 数字思考者50人 探访中国50位独具代表的数字化思考者 我们理解的 TechThinker 涵盖了中国数字化浪潮中的技术践行者 政策制定者与投资决策者 在这场长达10年的乘风破浪中 我们每个人都在分享技术进步的果
  • docker原理详解

    一 docker简介 docker是一个虚拟环境容器 可以将你的开发环境 代码 配置文件等一并打包到这个容器中 并发布和应用到任意平台中 docker容器和虚拟机都有虚拟隔离的特性 所以一般都会拿虚拟机和docker容器作比较 二 dock
  • C++数据结构 矩阵的转置、镜像及旋转

    C 数据结构 矩阵的转置 镜像及旋转 矩阵介绍 C 中的矩阵是一种二维数组 用于存储数值数据 矩阵可以用于存储图像数据 以及科学和工程计算中的数据 常用于以下场景 数学运算 矩阵乘法 行列式计算 特征值分解等 图像处理 图像缩放 旋转 颜色
  • facebook 审请AppID、AppSecret注意问题

    facebook https developers facebook com https developers facebook com apps 1596024967362217 dashboard 账号 密码 步骤 1 填入应用的包名
  • 文件夹上传到云服务器,文件夹怎么上传到云服务器上

    文件夹怎么上传到云服务器上 内容精选 换一换 RedisShake是一款开源的Redis迁移工具 支持Cluster集群的在线迁移与离线迁移 备份文件导入 但是部署在其他云厂商Redis服务上的Cluster集群数据 由于SYNC PSYN
  • MBR、GPT、LVM分区

    GPT分区 支持大于2T的空间分区UEFI系统 支持128个主分区 parted mklabel New disk label type gpt parted mkpart Partition name vdb1 File system t
  • 搭建zookeeper集群的时候报: JAVA_HOME is not set and java could not be found in PATH.错误

    我在搭建zookeeper集群的时候总是报 JAVA HOME is not set and java could not be found in PATH 的错误 但是我的java环境是没问题的 这个问题困扰我两天了 终于解决了 在此记录
  • 知道这20个正则表达式,能让你少写1,000行代码

    正则表达式 一个十分古老而又强大的文本处理工具 仅仅用一段非常简短的表达式语句 便能够快速实现一个非常复杂的业务逻辑 熟练地掌握正则表达式的话 能够使你的开发效率得到极大的提升 正则表达式经常被用于字段或任意字符串的校验 如下面这段校验基本
  • springcloud微服务系列教程(一) 什么是微服务?为什么要用springcloud?

    前言 这两年 微服务 一词被传得很火 关于微服务的文章在各大技术论坛和博客不断的兴起 不断被转发和评论 技术人员之间的交流也越来越多的青睐微服务这一话题 仿佛不懂微服务就不是一个合格的技术开发者 就连有些公司招聘的要求上都要求应聘者必须掌握
  • Hspice获取节点电流的方法

    如果mos调用时语句为 MNM1 则端口电流输出为 i1 x1 MNM1 表示输出子电路x1里面Device MNM1的第一个节点电流 如果调用语句为 XNM1 用于subckt模型Device的电流输出 则端口电流输出为 isub x1
  • Unity的Text Mesh Pro文字显示重叠处理

    在使用Text Mesh Pro的时候 出现文字重叠 如图 在编辑器内显示是正确的 最后发现是换行造成的 原本的文字是从pdf中复制过来 就会重叠 在记事本中删除换行用回车再次换行就能正确显示
  • CCS5.2.1/5.5 错误-No source available for main()

    1 错误现象 在CCS5 2 1开发环境中从别处导入项目并编译完成后 下载程序时出现如下图所示错误 备注 当前使用的compiler版本为C6000v7 4 14 2 解决办法 进入项目属性设置页面 可以看到当前的调试模式为 Suppres
  • 详解PyCharm配置Anaconda的艰难心路历程

    本文来源于公众号 csdn2299 喜欢可以关注公众号 程序员学府 这篇文章主要介绍了详解PyCharm配置Anaconda的艰难心路历程 小编觉得挺不错的 现在分享给大家 也给大家做个参考 一起跟随小编过来看看吧 在安装好pycharm后
  • 基于JAVA+SpringBoot+VUE的心理健康测试系统的设计与实现

    全网粉丝20W csdn特邀作者 博客专家 CSDN新星计划导师 java领域优质创作者 博客之星 掘金 华为云 阿里云 InfoQ等平台优质作者 专注于Java技术领域和毕业项目实战 文末获取项目下载方式 一 项目背景介绍 随着现代社会的
  • Redis常用的5种数据类型底层结构是怎样构成的

    前言 Redis是一个基于内存中的数据结构存储系统 可以用作数据库 缓存和消息中间件 Redis支持五种常见对象类型 字符串 String 哈希 Hash 列表 List 集合 Set 以及有序集合 Zset 我们在日常工作中也会经常使用它
  • 架构师成长之路

    延迟队列实现 基于监听key过期实现的延迟队列实现 这里需要继承KeyspaceEventMessageListener类来实现监听redis键过期 public class KeyExpirationEventMessageListene
  • Java CGLIB动态代理示例

    1 CGLIB动态代理简介 JDK动态代理是利用反射机制生成一个实现代理接口的匿名类 在调用具体方法前调用InvokeHandler来处理 而cglib动态代理是利用asm开源包 对代理对象类的class文件加载进来 通过修改其字节码生成子