【spring】jdk动态代理和cglib动态代理的区别
创始人
2025-05-30 20:18:46
0

目录

        • 一、说明
        • 二、区别
        • 三、代码示例
          • 3.1 静态代理
          • 3.2 jdk动态代理
          • 3.3 cglib动态代理

一、说明

  • 1.spring aop中的动态代理主要有两种方式,jdk动态代理和cglib动态代理
  • 2.从实现接口、继承父类的角度讨论区别
  • 3.从限制角度讨论区别
  • 4.从性能上讨论区别

二、区别

  • 1.jdk动态代理只提供实现接口的目标类代理,不支持没有实现接口的目标类的代理。如果目标类没有实现接口,只能用cglib代理
  • 2.jdk动态代理会在运行时为目标类生成一个动态代理类$proxy*.class。cglib的底层是通过ASM在运行时动态生成目标类的子类,还会有其它类
  • 3. jdk动态代理的代理类实现了目标类实现的接口,并且会实现接口所有方法来代码增强。cglib动态代理会重写父类所有的方法来代码增强
  • 4.jdk动态代理调用时先去调用处理类进行增强,再通过反射的方式调用目标类的方法。cglib动态代理调用时先通过代理类进行增强,再直接调用父类对应的方法进行调用目标方法
  • 5.jdk动态代理如果目标类未实现接口则无法代理,cglib是通过继承的方式来动态代理,若目标类被final关键字修饰,则无法使用cglib做动态代理
  • 6.性能上:在老版的jdk,jdk代理生成的类速度快,通过反射调用慢,cglib是jdk代理速度的10倍左右,jdk在版本每次升级都会有很大的性能提升,cglib停滞不前,jdk7 8的动态代理性能在1万次实验中比cglib要快20%左右

三、代码示例

3.1 静态代理
package com.proxy.staticproxy;public interface SellTicket {void sell();
}
package com.proxy.staticproxy;public class TrainStation implements SellTicket{@Overridepublic void sell() {System.out.println("火车站售票");}}
package com.proxy.staticproxy;public class ProxyPoint implements SellTicket{//声明火车类对象private TrainStation trainStation = new TrainStation();@Overridepublic void sell() {System.out.println("代售点收取服务费");trainStation.sell();}public static void main(String[] args) {ProxyPoint proxyPoint = new ProxyPoint();proxyPoint.sell();}
}
3.2 jdk动态代理
package com.proxy.jdkproxy;import com.proxy.staticproxy.SellTicket;
import com.proxy.staticproxy.TrainStation;import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;public class ProxyFactory {private TrainStation trainStation = new TrainStation();public SellTicket getProxyPoint() {/*** ClassLoader loader: 类加载器,用于加载代理类。可以通过目标对象获取类加载器* Class[] interfaces: 代理类实现的接口的字节码对象* InvocationHandler h: 代理对象的调用处理程序*/SellTicket sellTicket = (SellTicket)Proxy.newProxyInstance(trainStation.getClass().getClassLoader(), trainStation.getClass().getInterfaces(),new InvocationHandler() {/*** @param proxy 代理对象 proxyObject是同一个对象,在invoke方法中基本不用* @param method 对接口中的方法进行封装的method对象* @param args 调用方法的实际参数* @return 方法返回值* @throws Throwable*/@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {// 代码增强System.out.println("代理点收取服务费");Object object = method.invoke(trainStation, args);return object;}});return sellTicket;}public static void main(String[] args) {ProxyFactory proxyPoint = new ProxyFactory();SellTicket sellTicket = proxyPoint.getProxyPoint();sellTicket.sell();}
}
3.3 cglib动态代理

cglibcglib2.2.2
package com.cglib;import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;import java.lang.reflect.Method;public class ProxyFactory implements MethodInterceptor {private TrainStation trainStation = new TrainStation();public TrainStation getTrainStation(){//创建Enhancer对象,类似于JDK代理中的Proxy类Enhancer enhancer = new Enhancer();//设置父类的字节码对象enhancer.setSuperclass(TrainStation.class);//设置回调函数enhancer.setCallback(this);//创建代理对象TrainStation trainStation = (TrainStation)enhancer.create();return trainStation;}public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {// 代码增强System.out.println("代售点收取服务费用");Object obj = method.invoke(trainStation, objects);return obj;}public static void main(String[] args) throws Exception {ProxyFactory proxyFactory = new ProxyFactory();TrainStation trainStation = proxyFactory.getTrainStation();trainStation.sell();}
}

相关内容

热门资讯

保存时出现了1个错误,导致这篇... 当保存文章时出现错误时,可以通过以下步骤解决问题:查看错误信息:查看错误提示信息可以帮助我们了解具体...
汇川伺服电机位置控制模式参数配... 1. 基本控制参数设置 1)设置位置控制模式   2)绝对值位置线性模...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
表格中数据未显示 当表格中的数据未显示时,可能是由于以下几个原因导致的:HTML代码问题:检查表格的HTML代码是否正...
本地主机上的图像未显示 问题描述:在本地主机上显示图像时,图像未能正常显示。解决方法:以下是一些可能的解决方法,具体取决于问...
表格列调整大小出现问题 问题描述:表格列调整大小出现问题,无法正常调整列宽。解决方法:检查表格的布局方式是否正确。确保表格使...
不一致的条件格式 要解决不一致的条件格式问题,可以按照以下步骤进行:确定条件格式的规则:首先,需要明确条件格式的规则是...
Android|无法访问或保存... 这个问题可能是由于权限设置不正确导致的。您需要在应用程序清单文件中添加以下代码来请求适当的权限:此外...
【NI Multisim 14...   目录 序言 一、工具栏 🍊1.“标准”工具栏 🍊 2.视图工具...
银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...