动态代理Proxy和Cglib
大概过程#
程序运行期间动态生成字节码文件,然后加载到内存里面,生成代理对象
静态代理的时候,代理类和被代理类必须实现同一个接口,
动态代理代码#
public class MyCalculator implements Calculator{ @Override public int add(int i, int j){ int result = i + j; return result; } @Override public int sub(int i, int j){ int result = i - j; return result; } @Override public int mul(int i, int j){ int result = i * j; return result; } @Override public int div(int i, int j){ int result = i / j; return result; } } public class CalculatorProxy{ public static Calculator getProxy(){ // 获取类加载器 ClassLoader classLoader = calculator.getClass().getClassLoader(); // 获取要实现的接口 Class<?> interfaces = calculator.getClass().getInterfaces(); InvocationHandler h = new InvocationHandler(){ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable{ try{ Object result = method.invoke(calculator, args); return result; }catch(Exception e){ e.printStackTrace(); } } } Proxy.newProxyInstance(); } } public class Test{ public static void main(String[] args){ Calculator proxy = CalculatorProxy.getProxy(new MyCalculator()); System.out.println(proxy.add(1,1)); System.out.println(proxy.getClass()); } }
ASM是Java字节码操控框架,动态生成类或增强既有类的功能
ASM可以直接产生二进制class文件,可以在类被加载前动态改变类的行为
CGlib#
public class MyCalculator{ public int add(int i, int j){ int result = i + j; return result; } public int sub(int i, int j){ int result = i - j; return result; } public int mul(int i, int j){ int result = i * j; return result; } public int div(int i, int j){ int result = i / j; return result; } } public class MyCglig implements MethodInterceptor{ @Override public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable{ System.out.println("输出前"); Object o = proxy.invokeSuper(obj, args); System.out.println("输出后"); return o; } } public class Test{ public static void main(String[] args){ // 动态代理创建的class文件存储到本地 System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "d:\\code"); // 创建cglib获取代理对象的操作对象 Enhancer enhancer = new Enhancer(); // 设置enhancer对象的父类 enhancer.setSuperclass(MyCalculator.class); // 设置enhancer的回调对象 enhancer.setCallback(new MyCglib()); // 创建代理对象 Object o = enchancer.create(); MyCalculator MyCalculator = (MyCalculator)enhancer.create(); MyCalculator.add(1, 1); System.out.println(MyCalculator.getClass()); } }
作者:BigBender
出处:https://www.cnblogs.com/BigBender/p/14240478.html
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
2020-01-10 编译原理(清华大学出版社)-- 文法和语言 -- 上下文无关文法及其语法树
2020-01-10 编译原理(清华大学出版社)-- 文法和语言 -- 文法和语言的形式定义
2020-01-10 编译原理(清华大学出版社)-- 文法和语言 -- 文法的类型