不管是Java SDK代理还是cglib代理,其实都属于动态代理。我们从基本理论来分析:
概念
动态代理是一种强大的功能,它可以在运行时动态创建一个类,实现一个或多个接口,可以在不修改原有类的基础上动态为通过该类获取的对象添加方法、修改行为等。
应用场景
动态代理是实现面向切面的编程AOP(Aspect Oriented Programming)的基础。切面的例子有日志、性能监控、权限检查、数据库事务等。
实现方式
一种是Java SDK提供的
另外一种是第三方库(如cglib)提供的
Java SDK动态代理
创建代理对象可分为三步:
1️⃣ 通过Proxy.getProxyClass创建代理类定义,类定义会被缓存;
2️⃣ 获取代理类的构造方法,构造方法有一个InvocationHandler类型的参数;
3️⃣ 创建InvocationHandler对象,创建代理类对象。
Proxy.getProxyClass需要两个参数:一个是ClassLoader;另一个是接口数组。它会动态生成一个类,类名以$Proxy开头,后跟一个数字。
cglib动态代理
Java SDK动态代理的局限在于,它只能为接口创建代理,返回的代理对象也只能转换到某个接口类型,如果一个类没有接口,或者希望代理非接口中定义的方法,那就没有办法了。有一个第三方的类库cglib,可以做到这一点,Spring、Hibernate等都使用该类库。
被代理的类没有接口,getProxy()为一个类生成代理对象,这个代理对象可以安全地转换为被代理类的类型,它使用了cglib的Enhancer类。Enhancer类的setSuperclass设置被代理的类,setCallback设置被代理类的public非final方法被调用时的处理类。
Java SDK代理与cglib代理比较
Java SDK代理面向的是一组接口,它为这些接口动态创建了一个实现类。接口的具体实现逻辑是通过自定义的InvocationHandler实现的,这个实现是自定义的,也就是说,其背后都不一定有真正被代理的对象,也可能有多个实际对象,根据情况动态选择。cglib代理面向的是一个具体的类,它动态创建了一个新类,继承了该类,重写了其方法。
从代理的角度看,Java SDK代理的是对象,需要先有一个实际对象,自定义的InvocationHandler引用该对象,然后创建一个代理类和代理对象,客户端访问的是代理对象,代理对象最后再调用实际对象的方法;cglib代理的是类,创建的对象只有一个。
如果目的都是为一个类的方法增强功能,Java SDK要求该类必须有接口,且只能处理接口中的方法,cglib没有这个限制。
爱都给你,【点赞】和【在看】都给我!
原创文章 你是否也被面试官问到JavaSDK代理与cglib代理的区别?,版权所有
如若转载,请注明出处:https://www.itxiaozhan.cn/202212435.html