cglib

ASM是一个非常高效的Java字节码操控和分析框架,它允许开发者在运行时或者编译时期动态地生成、改变或者分析类。ASM提供的功能强大且灵活,适用于诸如框架开发、代码优化、代码生成等多种场景

需求:用 asm 编写一个类并运行输出hello word

依赖

<dependency>

    <groupId>org.ow2.asm</groupId>

    <artifactId>asm</artifactId>

    <version>9.1</version>

</dependency>

public static void main(String[] args) throws Exception {

         // 类名,包括包名,这里简化处理,不指定包名
        String className = "com.asm.test.ExampleClass";
        String fullName = className.replace('.', '/'); // 将点换成斜杠,因为ASM内部使用的是内部类名表示法

        // 创建ClassWriter对象,用于生成字节码
        ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);

        // 定义类,public class ExampleClass
        cw.visit(Opcodes.V1_8, // Java版本号,这里是Java 8
                Opcodes.ACC_PUBLIC, // 类访问修饰符,这里是public
                fullName, // 类名
                null, // 类签名,这里省略
                "java/lang/Object", // 父类,这里是Object
                null); // 实现的接口,这里没有实现任何接口

        // 添加默认构造函数
        MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null);
        mv.visitVarInsn(Opcodes.ALOAD, 0); // 加载this引用
        mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false); // 调用父类构造函数
        mv.visitInsn(Opcodes.RETURN); // 返回
        mv.visitMaxs(1, 1); // 设置最大栈和局部变量大小,这里简化处理
        mv.visitEnd();

        // 添加sayHello()方法
        mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "sayHello", "()V", null, null);
        mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
        mv.visitLdcInsn("Hello, World!"); // 将字符串常量推入栈顶
        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false); // 调用println方法
        mv.visitInsn(Opcodes.RETURN);
        mv.visitMaxs(2, 1); // 设置最大栈和局部变量大小
        mv.visitEnd();

        // 结束类定义
        cw.visitEnd();

        // 生成字节码到文件
        byte[] code = cw.toByteArray();
        FileOutputStream fos = new FileOutputStream("target/classes/"+fullName + ".class");
        fos.write(code);
        fos.close();

        System.out.println("Generated class file: " + className + ".class");
        // 加载ExampleClass
        Class<?> exampleClass = Class.forName(className); // 注意这里的类名不需要加.class
        
        // 创建ExampleClass的实例
        Object instance = exampleClass.getDeclaredConstructor().newInstance();
        
        // 获取sayHello方法
        Method sayHelloMethod = exampleClass.getMethod("sayHello");
        
        // 调用sayHello方法
        sayHelloMethod.invoke(instance);

    }

CGlib (Code Generation Library) 是一个强大的高性能的代码生成库,它为Java语言提供了一个非常便利的API来扩展Java类与实现接口。不同于ASM库直接操作字节码,CGlib采取了更高层次的抽象,使得开发者可以以面向对象的方式创建代理类或者子类,而无需了解底层字节码的细节。CGlib主要用于以下几个场景:

  1. 动态代理:当不能使用Java原生的java.lang.reflect.Proxy(仅能代理实现了接口的类)时,CGlib可以创建目标类的子类作为代理,因此适用于没有实现接口的类的增强。

  2. AOP(面向切面编程):在AOP框架中,如Spring AOP,默认情况下使用JDK动态代理,但若目标对象没有实现接口,则转而使用CGlib来创建代理对象,实现在方法前后插入自定义逻辑(如日志记录、事务管理等)。

  3. 持久化框架:一些ORM(对象关系映射)框架,如Hibernate的动态代理功能,可能会用到CGlib来实现延迟加载等特性。

  4. 其他框架与库:许多Java应用框架,如Spring、MyBatis等,都可能间接使用CGlib来增强或代理对象。

使用cglib创建代理

依赖

    <dependency>

        <groupId>cglib</groupId>

        <artifactId>cglib</artifactId>

        <version>3.3.0</version>

    </dependency>


public class CGlibProxyExample implements MethodInterceptor {

    public Object getProxy(Class clazz) {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(clazz);
        // enhancer.setInterfaces(new Class[]{SomeInterface.class});
        // 设置回调方法
        enhancer.setCallback(this);
        // 创建并返回代理对象
        return enhancer.create();
    }

    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        System.out.println("Before method execution");
        Object result = proxy.invokeSuper(obj, args); // 调用原始方法
        System.out.println("After method execution");
        return result;
    }

    public static void main(String[] args) {
        CGlibProxyExample example = new CGlibProxyExample();
        SomeService proxy = (SomeService) example.getProxy(SomeService.class);
        proxy.doSomething();
        // ((SomeInterface)proxy).doOtherSomething();
    }
}

public class SomeService {
    public void doSomething() {
        System.out.println("do something exe");
    }
}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/768833.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

OpenELM:开启开放训练和推理框架的高效语言模型家族

随着大模型模型规模的增长&#xff0c;这些强大工具的透明度、可复现性和对数据偏见的敏感性也引起了人们的关注。这些问题不仅关系到研究的开放性和公平性&#xff0c;也关系到模型输出的可信度和安全性。为了应对这些挑战&#xff0c;Apple的研究团队发布了名为OpenELM的新一…

守护进程到底是什么?如何创建?(图文并茂,你不得不看的一篇文章)

目录 守护进程&#xff08;Daemon Process&#xff09;详解 守护进程的特点 创建守护进程的步骤 用守护进程实现输入Hello功能 守护进程的用途 如何查看我们的守护进程&#xff1f; 1. ps 命令 2. top 命令 总结 守护进程&#xff08;Daemon Process&#xff09;详解 …

如何在主动动态安全中使用人工智能驱动的威胁分类提高防御精准度

面对当今世界不断演变的网络威胁&#xff0c;人工智能和网络安全将会发挥重要的防护作用。在数据泄露和网络攻击日益突出的时代&#xff0c;人工智能和网络安全之间的合作成为数字安全战场上的强大盟友。 本文将深入研究这两个领域的融合&#xff0c;揭示它们在彻底改变威胁检测…

Java---Mybatis详解二

雄鹰展翅凌空飞&#xff0c; 大江奔流不回头。 壮志未酬心未老&#xff0c; 豪情万丈任遨游。 巍巍高山攀顶峰&#xff0c; 滔滔黄河入海流。 风云变幻凭君舞&#xff0c; 踏遍天涯尽逍遥。 目录 一&#xff0c;环境准备 二&#xff0c;删除 三&#xff0c;删除(预编译SQL) 为什…

奇瑞被曝强制加班,“896”成常态且没有加班费

ChatGPT狂飙160天&#xff0c;世界已经不是之前的样子。 更多资源欢迎关注 7 月 2 日消息&#xff0c;一位认证为“奇瑞员工”的网友近期发帖引发热议&#xff0c;奇瑞汽车内部存在强制加班行为&#xff0c;每周加班时长需大于 20 小时并且没有加班费&#xff0c;仅补贴 10 元…

CJSON库

目录 一、介绍 1、JSON是什么 2、为什么使用CJSON 3、JSON格式 二、使用CJSON构造JSON 1、创建对象 2、添加字段 3、转换格式 4、释放对象 三、使用CJSON解析JSON 1、解析数据 2、 获取字段 3、释放对象 一、介绍 1、JSON是什么 JSON是什么呢&#xff1f;JSON全称…

Android studio 打包低版本的Android项目报错

一、报错内容 Execution failed for task :app:packageRelease. > A failure occurred while executing com.android.build.gradle.internal.tasks.Workers$ActionFacade> com.android.ide.common.signing.KeytoolException: Failed to read key key0 from store "…

如何创建移动类型

第一步打开事务代码&#xff1a; OMJJ 下面这个工作区可以不填&#xff0c;或者填入你的范围&#xff08;例如我准备copy Z52成为Z54 那么就可以输入从Z52到Z54&#xff0c;SAP的这个操作就是这么怪&#xff0c;哈哈&#xff09;不然就会出现一个这样的报错“在工作区中指定关…

聚焦西安应博会|2024西安城市安全应急产业展9月精彩呈现

2024西安城市安全应急产业博览会 时间&#xff1a;2024年9月12日-14日 地点&#xff1a;西安国际会展中心 运营&#xff1a;西安西部文化产业博览会有限公司 【展会简介】 为推动安全应急装备向智能化、成套化、专业化方向发展&#xff0c;迎接新质生产力在应急产业新技术…

在C++中,工厂模式的思考(《C++20设计模式》及常规设计模式对比)

文章目录 一、前言二、讲解1、构造函数的弊端2、工厂方法&#xff08;解决上述弊端&#xff09;3、简单工厂3.1 **UML类图**3.2 **实现** 4、工厂模式4.1 **UML类图**4.2 **实现** 5、抽象工厂5.1 **UML类图**5.2 **实现** 三、总结 一、前言 在看《C20设计模式》一书中产生了…

【软件测试】快速定位bug,编写测试用例

作为一名测试人员如果连常见的系统问题都不知道如何分析&#xff0c;频繁将前端人员问题指派给后端人员&#xff0c;后端人员问题指派给前端人员&#xff0c;那么在团队里你在开发中的地位显而易见 &#xff0c;口碑、升值、加薪那应该是你遥不可及的梦 但是作为测试人员来说&…

【ARMv8/v9 GIC 系列 5 -- GIC GICD_CTRL 使用详细介绍】

文章目录 GICD_CTRLGICD_CTLR 寄存器结构RWP&#xff08;Register Write Pending&#xff09;E1NWF&#xff08;Enable 1 of N Wakeup Functionality&#xff09;DS&#xff08;Disable Security&#xff09; 亲和性路由&#xff08;Affinity Routing&#xff09;ARE_NSARE_S 中…

华侨大学24计算机考研数据速览,专硕22408复试线290分,学硕11408接收调剂!

华侨大学计算机专业创建于1980年&#xff0c;是福建省最早设立计算机专业的高校之一。1982年成立计算机系&#xff0c;2008年成立计算机科学与技术学院。根据“华侨大学计算机科学与技术学院网站”资料&#xff0c;该院有计算机科学与技术、软件工程、网络工程3个本科专业&…

Mysql-基础-DDL操作

1、数据库操作 查询 查询所有数据库 show databases; 创建 创建数据库 create database [if not exists] 数据库名 使用及查询 use 数据库名 select database() 查询当前所处数据库 删除 drop database [if not exists] 数据库名 2、表操作 查询当前库中的所…

使用Python绘制彩虹效果:动态彩虹动画

文章目录 引言准备工作前置条件 代码实现与解析导入必要的库初始化Pygame定义绘制彩虹函数定义颜色列表主循环 完整代码 引言 彩虹是自然界中最美丽的现象之一。通过编程&#xff0c;我们可以将这一奇妙的景象带到屏幕上。在这篇博客中&#xff0c;我们将使用Python来创建一个…

如何优化网站SEO排名?

选择那些容易排名的关键词。使用工具找到那些竞争少但有流量的词语。其次&#xff0c;内部链接非常重要。通过合理的内部链接&#xff0c;可以提升各个页面的权重。 增加FAQ部分能帮助你捕捉更多的长尾关键词流量。争取出现在精选摘要的位置&#xff0c;可以直接提升你的曝光率…

django 逆向生成对应数据库表的models模型类 —— python

一&#xff0c;在setting.py中配置好连接数据库的参数 在setting中的DATABASESZ中配置默认参数&#xff0c;并在INSTALLED_APPS中导入模块名。 DATABASES {default:{ENGINE: django.db.backends.mysql, # 数据库引擎NAME: jljupcs, # 数据库名称HOST: 127.0.0.1, # 数据库…

【设计模式】策略模式(定义 | 特点 | Demo入门讲解)

文章目录 定义策略模式的结构 QuickStart | DemoStep1 | 策略接口Step2 | 策略实现Step3 | 上下文服务类Step4 | 客户端 策略模式的特点优点缺点 定义 策略模式Strategy是一种行为模式&#xff0c;它能定义一系列算法&#xff0c;并将每种算法分别放入到独立的类中&#xff0c…

解决pip安装时的“SyntaxError: invalid syntax”错误

项目场景&#xff1a; 项目中有新的成员加入时&#xff0c;第一步就是安装开发环境&#xff0c;然而往往同样的机器、同样的配置&#xff0c;我们却总能遇到各种各样不同的问题。 今天分享一个简单的操作问题。 问题描述 项目用到pandas&#xff0c;安装pandas时遇到Syntax…

代码随想录-Day46

121. 买卖股票的最佳时机 给定一个数组 prices &#xff0c;它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。 你只能选择 某一天 买入这只股票&#xff0c;并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。 返回你可以从…