动态代理

反射最大的作用就在于我们可以不在编译时知道某个对象的类型,而在运行时得到。

反射 一般使用 Class.forName()方法;

动态代理就是实现InvocationHandler 接口;通过reflect.Proxy的类的newProxyInstance方法就可以得到这个接口的实例

实现动态代理的方式有很多,比如JDK自身提供的动态代理,就是主要利用反射机制.还有其他的实现方式,比如利用传说中更高性能的字节码操作机制,类似ASM,cglib(基于ASM),Javassist等

JDK动态代理:
1.创建一个实现接口InvocationHandler的类,它必须实现invoke方法

2.创建需要被代理接口和实现类

3.通过Proxy的静态方法newProxyInstance(ClassLoaderloader, Class[] interfaces, InvocationHandler h)创建一个代理

4.通过代理调用方法

5.生成的动态代理类会调用InvocationHandler实现类中的invoke方法

6.invoke方法中我们可以选择执行被代理实现类的方法,并在其前后进行处理


在Dubbo中,没有使用CGLib进行代理,而是使用JDK和Javassist来进行动态代理!动态代理是无法用反射做的,只能靠动态生成字节码。
选择代理方式的考虑因素:
使用的难易程度。
功能,比如JDK的代理只能通过接口实现,而CGLib则没这个限制。
生成的字节码的效率,包括创建的效率和运行的效率。
生成的字节码大小,为什么说这也比较重要?这和生成的Class和其实例的大小相关。
 
 JDK动态代理和cglib代理区别:
 1.JDK动态代理只能对实现了接口的类生成代理,而不能针对类
 2.CGLIB是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法(继承)
 3.Cglib代理是功能最为强大的一种代理方式,因为其不仅解决了静态代理需要创建多个代理类的问题,还解决了jdk代理需要被代理对象实现某个接口的问题。对于需要代理的类,如果能为其创建一个子类,并且在子类中编写相关的代理逻辑,因为“子类instanceof父类”,因而在进行调用时直接调用子类对象的实例,也可以达到代理的效果。Cglib代理的原理实际上是动态生成被代理类的子类字节码,由于其字节码都是按照jvm编译后的class文件的规范编写的,因而其可以被jvm正常加载并运行。这也就是Cglib代理为什么不需要为每个被代理类编写代理逻辑的原因。唯一需要注意的是,CGLib不能对声明为final的方法进行代理,因为CGLib原理是动态生成被代理类的子类。
 
 Spring aop中使用的代理模式:
 (1)当Bean实现接口时,Spring就会用JDK的动态代理

 (2)当Bean没有实现接口时,Spring使用CGlib是实现

 (3)可以强制使用CGlib(在spring配置中加入<aop:aspectj-autoproxy proxy-target-class="true"/>)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值