博客
关于我
Java动态代理的实现方式
阅读量:794 次
发布时间:2023-01-28

本文共 2668 字,大约阅读时间需要 8 分钟。

Java动态代理的实现方式

什么是动态代理?

动态代理是一种编程模式,允许在运行时创建代理对象,以实现对目标对象的方法进行增强。代理对象与目标对象具有相同的接口,但在执行特定逻辑时嵌入增强功能或 调用其他对象的方法。动态代理通过动态生成代理对象的方式,为目标对象添加功能,如日志记录、事务管理等,减少代码耦合,降低代码重复率。

动态代理的作用

动态代理适用于在不侵入目标类逻辑的前提下,添加公共功能。例如:

  • 记录日志记录:跟踪对象方法的调用情况。
  • 管理事务:确保方法执行的原子性和持久性。
  • 监控性能:统计方法执行时间。

这种方法能在不修改目标对象代码的前提下,降低代码耦合度,减少重复代码。

动态代理的使用场景

动态代理广泛应用于:

  • Spring AOP:通过动态代理实现方法级别的切割,如事务管理、日志记录等。
  • 手动创建代理:针对特定场景,按需动态生成代理对象。

动态代理的实现技术

1. JDK动态代理技术(基于接口)
  • 适用条件:目标类必须有接口。
  • 实现方式:通过Proxy.newProxyInstance方法创建代理对象。开源框架如Spring AOP默认使用该技术。
2. Cglib动态代理技术(基于子类)
  • 适用条件:目标类没有接口且不能被final修饰。
  • 实现方式:通过生成目标类的动态子类实现。Spring AOP可通过配置强制使用此技术。

动态代理实现对比

特性 JDK动态代理技术 Cglib动态代理技术
目标类要求 有接口 无接口,不能有final修饰
生成方式 基于接口动态实现类 基于目标类生成动态子类
优点 非侵入性,代码独立性强 适用于不能实现接口或切断 inheritance
缺点 需要接口接口分离 難以处理 final 方法,不能链式调用

手动创建JDK动态代理

public interface JDKService {    void show(String s);}public class JDKServiceImpl implements JDKService {    @Override    public void show(String s) {        System.out.println("JDKService show......" + s);    }}public class JDKProxyDemo {    public static void main(String[] args) {        JDKService jdkService = new JDKServiceImpl();        Object proxyInstance = Proxy.newProxyInstance(            jdkService.getClass().getClassLoader(),            jdkService.getClass().getInterfaces(),            (proxy, method, args) -> {                System.out.println("Method: " + method.getName());                System.out.println("Args: " + Arrays.toString(args));                Object result = method.invoke(jdkService, args);                System.out.println("Result: " + result);                return result;            }        );        JDKService proxy = (JDKService) proxyInstance;        proxy.show("hello");    }}

Cglib动态代理手动创建

public class Target {    public void show(String s) {        System.out.println("Target show.......... " + s);    }}public class Advice {    public void before() {        System.out.println("Advice before ......");    }    public void after() {        System.out.println("Advice after .......");    }}public class CglibProxyDemo {    public static void main(String[] args) {        Target target = new Target();        Advice advice = new Advice();        // 动态增强器        Enhancer enhancer = new Enhancer();        enhancer.setSuperclass(Target.class); // 设置被代理类        // 回调增强        enhancer.setCallback((MethodInterceptor o, Method method, Object objects, MethodProxy methodProxy) -> {            advice.before();            Object result = method.invoke(target, objects);            advice.after();            return result;        });        Target proxy = (Target) enhancer.create();        proxy.show("hello");    }}

到这里,文章完成,涵盖了动态代理的实现方式,包括两种技术的特点及典型实现示例。文章结构清晰,便于阅读和理解。

转载地址:http://ynryk.baihongyu.com/

你可能感兴趣的文章
PHP系列:PHP 基础编程 2(时间函数、数组---实现登录&注册&修改)
查看>>
PHP系列:使用PHP实现登录注册功能的完整指南
查看>>
Python&aconda系列:cmd/powershell/anaconda prompt提示“系统找不到指定的路径”(亲测有效)
查看>>
Python&aconda系列:(W&L)Conda使用faiss-gpu报错及解决办法、安装numpy的坑、cmd执行Python脚本找不到第三方库、安装tensorflow-gpu时遇到的from
查看>>
python&anconda 系列:Pycharm在debug问题的N种解决方案(一般程序、web方向、人工智能方向)
查看>>
python&anconda系列(亲测有效):tensorflow AttributeError: ‘str’ object has no attribute ‘decode’
查看>>
python&anconda系列:tf.keras.backend.get_session()和keras.backend.get_会话()返回不同的会话对象(待解答)
查看>>
"WARNING: Increasing RAM size to 1GB" and "Cannot set up guest memory 'xxx.ram': Invalid argument".
查看>>
#if 0 #elif 1 #else #endif 用法
查看>>
(反射+内省机制的运用)简单模拟spring IoC容器的操作
查看>>
.Net(C#)实现异步编程
查看>>
.Net中webBrowser控件JS交互
查看>>
02-Docker镜像分类及操作秘籍,轻松掌握导出、导入、删除
查看>>
04-docker-commit构建自定义镜像
查看>>
05-docker系列-使用dockerfile构建镜像
查看>>
09-docker系列-docker网络你了解多少(下)
查看>>
10-docker系列-docker文件共享和特权模式
查看>>
#C2#S2.2~S2.3# 加入 factory/objection/virtual interface 机制
查看>>
#C8# UVM中的factory机制 #S8.1.4# 约束的重载
查看>>
#C8# UVM中的factory机制 #S8.2.3# 重载sequence哪些情形
查看>>