本篇内容主要讲解“Java JDK与cglib动态代理有哪些区别”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Java JDK与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%左右
package com.proxy.staticproxy; public interface SellTicket { void sell(); }
package com.proxy.staticproxy; public class TrainStation implements SellTicket{ @Override public void sell() { System.out.println("火车站售票"); } }
package com.proxy.staticproxy; public class ProxyPoint implements SellTicket{ //声明火车类对象 private TrainStation trainStation = new TrainStation(); @Override public void sell() { System.out.println("代售点收取服务费"); trainStation.sell(); } public static void main(String[] args) { ProxyPoint proxyPoint = new ProxyPoint(); proxyPoint.sell(); } }
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 */ @Override public 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(); } }
<!-- 引入cglib依赖包--> <dependency> <groupId>cglib</groupId> <artifactId>cglib</artifactId> <version>2.2.2</version> </dependency>
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(); } }
到此,相信大家对“Java JDK与cglib动态代理有哪些区别”有了更深的了解,不妨来实际操作一番吧!这里是亿速云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。