广州北大青鸟计算机职业培训学校
互联网技术培训、软件技术培训、大数据培训、云计算培训、数据分析培训信息网
当前位置:网站首页 > 软件教程 > Java技术 > 正文

JDK代理与Cglib代理实现分析

作者:admin发布时间:2020-09-11分类:Java技术浏览:1675


导读:JDK代理AOP实现  java.lang.reflect.Proxy,  代理提供用于创建动态代理类和实例的静态方法。只能针对接口创建代理  newProxyInstance()...

JDK代理AOP实现

  java.lang.reflect.Proxy,

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

  newProxyInstance()

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

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

  java.lang.reflect.InvocationHandler,

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

  invoke()

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

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

  1个公共静态void main(String [] args){

  2

  3 InvocationHandler ih = new InvocationHandler(){

  4

  5个公共对象调用(对象代理,方法方法,对象[]参数)

  6投掷{

  7 //拦截方法处理

  8返回null;

  9}

  10

  11};

  12

  13个Class []接口=新的Class [] {BankAccount.class};

  14

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

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

  17}

  18

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

  接口代码:

  1个公共接口BankAccount {

  2

  3布尔存款(BigDecimal货币);

  4

  5布尔取款(BigDecimal money);

  6

  7字符串getName();

  8

  9字符串getId();

  10}

  11

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

  1个公开最终类BankAccount $ 1扩展了Proxy实施BankAccount {

  2个私有静态方法m6;// getId

  3私有静态方法m4;//退出

  4个私有静态方法m5;// getName

  5个私有静态方法m2;// toString

  6私有静态方法m0; // hashCode

  7个私有静态方法m3;//存入

  8个私有静态方法m1;// 等于

  9

  10公共BankAccount $ 1(InvocationHandler ih){

  11超级(ih);

  12}

  13

  14个公共最终字符串getId(){

  15试试{

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

  17} catch(RuntimeException e){

  18掷e;

  19} catch(Throwable t){

  20抛出新的UndeclaredThrowableException(t);

  21}

  22}

  23

  24 public final boolean withdraw(BigDecimal paramBigDecimal){

  25试试{

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

  27个新的Object [] {paramBigDecimal}))。booleanValue();

  28} catch(RuntimeException e){

  29掷e;

  30} catch(Throwable t){

  31抛出新的UndeclaredThrowableException(t);

  32}

  33}

  34

  35 public final String getName(){

  36试试{

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

  38} catch(RuntimeException e){

  39掷e;

  40} catch(Throwable t){

  41抛出新的UndeclaredThrowableException(t);

  42}

  43}

  44

  45 public final String toString(){

  46试试{

  47 return(String)this.h.invoke(this,m2,null);复制代码

  48} catch(RuntimeException localRuntimeException){

  49抛出localRuntimeException;

  50} catch(Throwable t){

  51抛出新的UndeclaredThrowableException(t);

  52}

  53}

  54

  55 public final int hashCode(){

  56试试{

  57 return((Integer)this.h.invoke(this,m0,null))。intValue();复制代码

  58} catch(RuntimeException e){

  59掷e;

  60} catch(Throwable t){

  61抛出新的UndeclaredThrowableException(t);

  62}

  63}

  64

  65个公共最终布尔值存款(BigDecimal paramBigDecimal){

  66试试{

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

  68个新的Object [] {paramBigDecimal}))。booleanValue();

  69} catch(RuntimeException localRuntimeException){

  70抛出localRuntimeException;

  71} catch(Throwable localThrowable){

  72抛出新的UndeclaredThrowableException(localThrowable);

  73}

  74}

  75

  76静态{

  77试试{

  78平方米= Class.forName(“ BankAccount”)。getMethod(“ getId”,新Class [0]);

  79平方米= Class.forName(“ BankAccount”)。getMethod(“ withdraw”,

  80新的Class [] {Class.forName(“ java.math.BigDecimal”)});

  81平方米= Class.forName(“ BankAccount”)

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

  83平方米= Class.forName(“ java.lang.Object”)。getMethod(“ toString”,

  84个新Class [0]);

  85 m0 = Class.forName(“ java.lang.Object”)。getMethod(“ hashCode”,

  86个新Class [0]);

  87立方米= Class.forName(“ BankAccount”)。getMethod(“ deposit”,

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

  89平方米= Class.forName(“ java.lang.Object”)。getMethod(“ equals”,

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

  91} catch(NoSuchMethodException e){

  92抛出新的NoSuchMethodError(e.getMessage());

  93} catch(ClassNotFoundException e){

  94抛出新的NoClassDefFoundError(e.getMessage());

  95}

  96}

  97}

  98

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

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

  cglib是一个开源项目!是一个强大的,高性能,可以扩展的代码生成类库,它可以在运行期扩展Java类与实现Java接口。Spring可以通过该项目实现AOP的功能封装。

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

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

  1个公共类SimpleBean {

  2

  3 public void hello(){

  4 System.out.println(“ hi matthew!”);

  5}

  6}

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

  1类SimpleBean $$ EnhancerByCGLIB $$ 4c4a66a扩展了SimpleBean {

  2个私有静态最终方法CGLIB $ hello $ 0 $ Method;

  3

  4 public final void hello(){

  5如果(!this.CGLIB $ CONSTRUCTED)

  6 {

  7 super.hello();

  8返回;

  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 $ 4。 $ Proxy);

  19返回

  20

  21}

  22个super.hello();

  23返回;

  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回报;

  36}

  37

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

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

  祝好运!

  您的马修!

  (广州计算机培训转)



Java技术排行
标签列表
网站分类
文章归档
最近发表