- 联系电话 - - 来校路线 - 广州天河区五山路金华园区3楼307(华工南门)
您现在的位置: 计算机培训 >> 学校课程 >> Java培训 >> 正文
JDK Proxy与Cglib Proxy实现分析 作者:佚名    课程来源:本站原创    点击数:    更新时间:2011-10-11

  JDK Proxy AOP实现

  java.lang.reflect.Proxy,

  Proxy 提供用于创建动态代理类和实例的静态方法. 只能针对接口创建代理

  newProxyInstance()

  返回一个指定接口的代理类实例,该接口可以将方法调用指派到指定的调用处理程序

  (详见api文档)(广州计算机培训转)

  java.lang.reflect.InvocationHandler,

  InvocationHandler 是代理实例的调用处理程序 实现的接口。

  invoke()

  在代理实例上处理方法调用并返回结果。在与方法关联的代理实例上调用方法时,将在调用处理程序上调用此方法。

  动态代理的使用代码示例如下:

  1 public static void main(String[] args) {

  2

  3 InvocationHandler ih = new InvocationHandler() {

  4

  5 public Object invoke(Object proxy, Method method, Object[] args)

  6 throws Throwable {

  7 // 拦截方法处理

  8 return null;

  9 }

  10

  11 };

  12

  13 Class[] interfaces = new Class[] {BankAccount.class};

  14

  15 BankAccount bankAccount = (BankAccount) Proxy.newProxyInstance(ProxyTest

  16 .class.getClassLoader(), interfaces, ih);

  17 }

  18

  下面是动态代理生成的代码对应(通过反编译工具对字节码进行处理)

  接口代码:

  1 public interface BankAccount {

  2

  3 boolean deposit(BigDecimal money);

  4

  5 boolean withdraw(BigDecimal money);

  6

  7 String getName();

  8

  9 String getId();

  10 }

  11

  动态代理生成的字节码(反编译后的Java代码)

  1 public final class BankAccount$1 extends Proxy implements BankAccount {

  2 private static Method m6; // getId

  3 private static Method m4; // withdraw

  4 private static Method m5; // getName

  5 private static Method m2; // toString

  6 private static Method m0; // hashCode

  7 private static Method m3; // deposit

  8 private static Method m1; // equals

  9

  10 public BankAccount$1(InvocationHandler ih) {

  11 super(ih);

  12 }

  13

  14 public final String getId() {

  15 try {

  16 return (String) this.h.invoke(this, m6, null);

  17 } catch (RuntimeException e) {

  18 throw e;

  19 } catch (Throwable t) {

  20 throw new UndeclaredThrowableException(t);

  21 }

  22 }

  23

  24 public final boolean withdraw(BigDecimal paramBigDecimal) {

  25 try {

  26 return ((Boolean) this.h.invoke(this, m4,

  27 new Object[] { paramBigDecimal })).booleanValue();

  28 } catch (RuntimeException e) {

  29 throw e;

  30 } catch (Throwable t) {

  31 throw new UndeclaredThrowableException(t);

  32 }

  33 }

  34

  35 public final String getName() {

  36 try {

  37 return (String) this.h.invoke(this, m5, null);

  38 } catch (RuntimeException e) {

  39 throw e;

  40 } catch (Throwable t) {

  41 throw new UndeclaredThrowableException(t);

  42 }

  43 }

  44

  45 public final String toString() {

  46 try {

  47 return (String) this.h.invoke(this, m2, null);

  48 } catch (RuntimeException localRuntimeException) {

  49 throw localRuntimeException;

  50 } catch (Throwable t) {

  51 throw new UndeclaredThrowableException(t);

  52 }

  53 }

  54

  55 public final int hashCode() {

  56 try {

  57 return ((Integer) this.h.invoke(this, m0, null)).intValue();

  58 } catch (RuntimeException e) {

  59 throw e;

  60 } catch (Throwable t) {

  61 throw new UndeclaredThrowableException(t);

  62 }

  63 }

  64

  65 public final boolean deposit(BigDecimal paramBigDecimal) {

  66 try {

  67 return ((Boolean) this.h.invoke(this, m3,

  68 new Object[] { paramBigDecimal })).booleanValue();

  69 } catch (RuntimeException localRuntimeException) {

  70 throw localRuntimeException;

  71 } catch (Throwable localThrowable) {

  72 throw new UndeclaredThrowableException(localThrowable);

  73 }

  74 }

  75

  76 static {

  77 try {

  78 m6 = Class.forName("BankAccount").getMethod("getId", new Class[0]);

  79 m4 = Class.forName("BankAccount").getMethod("withdraw",

  80 new Class[] { Class.forName("java.math.BigDecimal") });

  81 m5 = Class.forName("BankAccount")

  82 .getMethod("getName", new Class[0]);

  83 m2 = Class.forName("java.lang.Object").getMethod("toString",

  84 new Class[0]);

  85 m0 = Class.forName("java.lang.Object").getMethod("hashCode",

  86 new Class[0]);

  87 m3 = Class.forName("BankAccount").getMethod("deposit",

  88 new Class[] { Class.forName("java.math.BigDecimal") });

  89 m1 = Class.forName("java.lang.Object").getMethod("equals",

  90 new Class[] { Class.forName("java.lang.Object") });

  91 } catch (NoSuchMethodException e) {

  92 throw new NoSuchMethodError(e.getMessage());

  93 } catch (ClassNotFoundException e) {

  94 throw new NoClassDefFoundError(e.getMessage());

  95 }

  96 }

  97 }

  98

  从动态代理生成的代码可以分析得到,所有的方法的调用,都会回调InvokeHanlder接口的实现类的invoke方法,并把实际调用的反射相关信息作为参数传给invoke方法。

  Cglib Proxy AOP实现(广州计算机培训转)

  cglib是一个开源项目! 是一个强大的,高性能,高质量的Code生成类库,它可以在运行期扩展Java类与实现Java接口。Spring很多地方借助该项目实现AOP的功能封装。

  CGLIB包的底层是通过使用一个小而快的字节码处理框架ASM,来转换字节码并生成新的类。通过使用CGLIB来为那些没有接口的类创建代理对象。

  Cglib的Proxy与JDK Proxy还是有一定的相似的,下面的例子,给大家一个基本的演示

  1 public class SimpleBean {

  2

  3 public void hello() {

  4 System.out.println("hi matthew!");

  5 }

  6 }

  Cglib 代理后(只给出了部分核心反编译后的Java代码)

  1 class SimpleBean$$EnhancerByCGLIB$$4c4a66a extends SimpleBean {

  2 private static final Method CGLIB$hello$0$Method ;

  3

  4 public final void hello( ) {

  5 if(!this.CGLIB$CONSTRUCTED)

  6 {

  7 super.hello();

  8 return;

  9

  10 }

  11 if(this.CGLIB$CALLBACK_0== null)

  12 {

  13 CGLIB$BIND_CALLBACKS(this);

  14

  15 }

  16 if(this.CGLIB$CALLBACK_0!= null)

  17 {

  18 this.CGLIB$CALLBACK_0.intercept(this,SimpleBean$$EnhancerByCGLIB$$4c4a66a.CGLIB$hello$0$Method,SimpleBean$$EnhancerByCGLIB$$4c4a66a.CGLIB$emptyArgs,SimpleBean$$EnhancerByCGLIB$$4c4a66a.CGLIB$hello$0$Proxy);

  19 return;

  20

  21 }

  22 super.hello();

  23 return;

  24 catch(RuntimeException aRuntimeException2)

  25 {

  26 catch(Throwable aRuntimeException2)

  27 {

  28 UndeclaredThrowableException JdecGenerated57 = new UndeclaredThrowableException(

  29 }

  30 }

  31

  32 final void CGLIB$hello$0( )

  33 {

  34 super.hello();

  35 return;

  36 }

  37

  注: 从上面的实现代理来看,Cglib对于标识 final 关键字的class无法进行代理操作。

  对于标识final的方法,也无法进行代理

  Good Luck!

  Yours Matthew!

  (广州计算机培训转)

学校路线 |网站地图| 学校优势 Copyright 2006-2016 All Rights Reserved 广州青大教育信息咨询有限公司 版权所有备案/许可证编号为粤ICP备11070650号-9 北大青鸟北京总部:北京阿博泰克北大青鸟信息技术有限公司广州计算机学校培训网 官方网址:www.itjspx.com 公司地址:广州市天河区五山路华南理工大学科技园金华园区3楼307(华工南门)