描述动态代理的几种实现方式 分别说出相应的优缺点

来自互联网wiki-HLWwiki
跳转至: 导航搜索

java > java基础


动态代理可以分为”静态代理”和“动态代理”,动态代理又分为“JDK 动态代理”和“CGLIB 动态代理”实现。

Hfdsddfteerererefdfd.png


静态代理:(如上图)代理对象和实际对象都继承了同一个接口,在代理对象中指向的是实际对象的实例,这样对外暴露的是代理对象而真正调用的是 Real Object

  • 优点:可以很好的保护实际对象的业务逻辑对外暴露,从而提高安全性。
  • 缺点:不同的接口要有不同的代理类实现,会很冗余。


JDK 动态代理:为了解决静态代理中,生成大量的代理类造成的冗余;JDK 动态代理只需要实现 InvocationHandler 接口,重写 invoke 方法便可以完成代理的实现, jdk的代理是利用反射生成代理类Proxyxx.class 代理类字节码,并生成对象,jdk动态代理之所以只能代理接口是因为代理类本身已经extends了Proxy,而java是不允许多重继承的,但是允许实现多个接口

从代理类的Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),targetObject.getClass().getInterfaces(), this);

获取方式来看,必须传入实现的接口

  • 优点:解决了静态代理中冗余的代理实现类问题。
  • 缺点:JDK 动态代理是基于接口设计实现的,如果没有接口,但会抛异常。


CGLIB 代理:由于 JDK 动态代理限制了只能基于接口设计,而对于没有接口的情况,JDK方式解决不了;CGLib 采用了非常底层的字节码技术,其原理是通过字节码技术为一个类创建子类,并在子类中采用方法拦截的技术拦截所有父类方法的调用,顺势织入横切逻辑,来完成动态代理的实现。

实现方式实现 MethodInterceptor 接口,重写 intercept 方法,通过 Enhancer 类的回调方法来实现。

  • 优点:没有接口也能实现动态代理,而且采用字节码增强技术,性能也不错。
  • 缺点:技术实现相对难理解些。


jdk和cglib动态代理实现的区别

  1. jdk动态代理生成的代理类和委托类实现了相同的接口;
  2. cglib动态代理中生成的字节码更加复杂,生成的代理类是委托类的子类,且不能处理被final关键字修饰的方法;
  3. jdk采用反射机制调用委托类的方法,cglib采用类似索引的方式直接调用委托类方法;

来自 <http://www.cnblogs.com/chinajava/p/5880887.html>