1、JDK 动态代理:底层采用的是Java反射技术,获取真正的代理类,代理对象会在jvm 中进行创建,通过指定接口的ClassLoader 来创建一个指定接口的代理对象,代理类会实现InvocationHandler接口,来拦截我们的接口请求,在invoke()中做增强与请求转发处理。
@SuppressWarnings("unchecked") publicT getProxy(Class interfaces) { // 1. jvm 内存中生成一个class 类 // 2. 根据该class 类反射一个代理对象 $Proxy@ return (T) Proxy.newProxyInstance(interfaces.getClassLoader(), new Class[] {interfaces}, this); } /** * invoke() 是 InvocationHandler 接口中代理的拦截方法, 此处覆盖该方法, 让它对目标接口的方法进行拦截 * * @param proxy 这个就是我们的代理类, 就是jdk 生成的那个以 $Proxy. 开头的代理类 * @param method interface.method() 目标接口中的方法 * @param args interface.method(args) 目标接口中的参数 * @return * @throws Throwable */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("TargetProxy 前置增强....."); // 调用目标接口中的方法 Object result = method.invoke(target, args); System.out.println("TargetProxy 后置增强....."); return result; } 2、CGLIB 动态代理:使用CGLIB实现动态代理,完全不受代理类必须实现接口的限制,CGLIB底层采用ASM字节码生成框架,使用字节码技术生成代理类,在JDK8之前,CGLIB动态要比JDK的动态代理(JDK使用的是Java反射)效率要高。唯一需要注意的是,如果被代理的类被final修饰,那么它将不可被继承,即不可被代理,同样,如果被代理的类中存在final修饰的方法,那么该方法也不可被代理。因为CGLIB原理是动态生成被代理类的子类。
3、javassist 动态代理:javassist与JDK代理类似,它是通过代理工厂来创建代理对象的,代理类实现MethodHandler接口,来拦截我们的接口请求,在invoke()中做增强与请求转发处理。
public Object getProxy(Class tClass) throws InstantiationException, IllegalAccessException { // 代理工厂 ProxyFactory proxyFactory = new ProxyFactory(); // 设置需要创建子类的父类 proxyFactory.setSuperclass(tClass); // 通过字节码技术动态创建子类实例 proxyFactory.writeDirectory = "D:\software\data\idea\mybatis-3-mybatis-3.5.4"; Object proxy = proxyFactory.createClass().newInstance(); // 在调用目标方法之前, Javassist会回调MethodHandler接口方法拦截, 在其中可以实现自己的代理增强方法, 类似JDK中的InvocationHandler ((ProxyObject) proxy).setHandler(this); // 返回代理对象 return proxy; } @Override public Object invoke(Object self, Method thisMethod, Method proceed, Object[] args) throws Throwable { System.out.println("Javassist 事务开始....."); // 调用目标类中的方法 Object result = proceed.invoke(self, args); System.out.println("Javassist 事务结束....."); return result; }
java动态代理三种方式是什么
2023-12-04
收藏 92
猜你喜欢
-
程序员知识
静态链表中如何删除指定元素
1、遍历数据链表,找到要删除的目标元素。 2、将要删除的节点从数据链表中摘除。 3、将要删除的节点添加到备用...
23-12-03 364 -
程序员知识
静态链表添加元素的步骤是什么
1、从备用链表中摘除一个节点,用于存储新元素。 2、找到要插入位置的前一个节点(即第n-1个节点),将该节点的...
23-12-04 319 -
程序员知识
静态链表存储数据元素时包含哪些信息
1、数据域:这是用于存储数据元素的值的部分。数据域的具体内容取决于具体的应用场景和需求,它可以是任何类型...
23-12-04 487 -
程序员知识
随机存取结构和顺序存取结构有哪些区别
1、定义不同:随机存取 (Random Access)当存储器中的数据被读取或写入时,所需要的时间与该数据所在的物理地址无关...
23-12-04 215 -
程序员知识
如何判断两个单链表相交
1、双指针法:首先计算两个链表的长度,让较长的链表先走差值步数,然后同时遍历两个链表,当遍历到相同的节点...
23-12-04 389 -
程序员知识
如何实现单链表的反转
1、迭代反转链表:该算法的实现思想非常直接,就是从当前链表的首元节点开始,一直遍历至链表的最后一个节点,...
23-12-04 234 -
程序员知识
链表中如何对元素增删改查
1、链表插入元素:向链表中增添元素,根据添加位置不同,可分为添加在头部、中间和末尾,虽然新元素的插入位置...
23-12-04 356 -
程序员知识
链表中的节点有哪几种
1、头节点:其实就是一个不存任何数据的空节点,通常作为链表的第一个节点。对于链表来说,头节点不是必须的,...
23-12-04 274