Java CGLib动态代理机制(全面解析)

 更新时间:2017年08月04日 08:24:37   投稿:jingxian  
下面小编就为大家带来一篇Java CGLib动态代理机制(全面解析)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧

一、首先说一下JDK中的动态代理:

JDK中的动态代理是通过反射类Proxy以及InvocationHandler回调接口实现的

但是,JDK中所要进行动态代理的类必须要实现一个接口,也就是说只能对该类所实现接口中定义的方法进行代理,这在实际编程中具有一定的局限性,而且使用反射的效率也并不是很高。

二、使用CGLib实现:

使用CGLib实现动态代理,完全不受代理类必须实现接口的限制,而且CGLib底层采用ASM字节码生成框架,使用字节码技术生成代理类,比使用Java反射效率要高。唯一需要注意的是,CGLib不能对声明为final的方法进行代理,因为CGLib原理是动态生成被代理类的子类。

下面,将通过一个实例介绍使用CGLib实现动态代理。

1、被代理类:

首先,定义一个类,该类没有实现任何接口,包含两个方法。

public class ConcreteClassNoInterface { 
 public String getConcreteMethodA(String str){ 
  System.out.println("ConcreteMethod A ... "+str); 
  return str; 
 } 
 public int getConcreteMethodB(int n){ 
  System.out.println("ConcreteMethod B ... "+n); 
  return n+10; 
 } 
}

2、拦截器:

定义一个拦截器。在调用目标方法时,CGLib会回调MethodInterceptor接口方法拦截,来实现你自己的代理逻辑,类似于JDK中的InvocationHandler接口。

public class ConcreteClassInterceptor implements MethodInterceptor{ 
 public Object intercept(Object obj, Method method, Object[] arg, MethodProxy proxy) throws Throwable { 
  System.out.println("Before:"+method); 
  Object object=proxy.invokeSuper(obj, arg); 
  System.out.println("After:"+method); 
  return object; 
 } 
} 

参数:Object为由CGLib动态生成的代理类实例,Method为上文中实体类所调用的被代理的方法引用,Object[]为参数值列表,MethodProxy为生成的代理类对方法的代理引用。

返回:从代理实例的方法调用返回的值。

其中,proxy.invokeSuper(obj,arg):

调用代理类实例上的proxy方法的父类方法(即实体类ConcreteClassNoInterface中对应的方法)

在这个示例中,只在调用被代理类方法前后各打印了一句话,当然实际编程中可以是其它复杂逻辑。

3、生成动态代理类:

Enhancer enhancer=new Enhancer(); 
enhancer.setSuperclass(ConcreteClassNoInterface.class); 
enhancer.setCallback(new ConcreteClassInterceptor()); 
ConcreteClassNoInterface ccni=(ConcreteClassNoInterface)enhancer.create(); 

这里Enhancer类是CGLib中的一个字节码增强器,它可以方便的对你想要处理的类进行扩展,以后会经常看到它。

首先将被代理类ConcreteClassNoInterface设置成父类,然后设置拦截器ConcreteClassInterceptor,最后执行enhancer.create()动态生成一个代理类,并从Object强制转型成父类型ConcreteClassNoInterface。

最后,在代理类上调用方法:

ccni.getConcreteMethodA("shensy"); 
ccni.getConcreteMethodB(0); 

查看控制台输出:

Before :public java.lang.String generic.cglib.proxy.ConcreteClassNoInterface.getConcreteMethodA(java.lang.String) 
ConcreteMethod A ... shensy 
After :public java.lang.String generic.cglib.proxy.ConcreteClassNoInterface.getConcreteMethodA(java.lang.String) 
Before :public int generic.cglib.proxy.ConcreteClassNoInterface.getConcreteMethodB(int) 
ConcreteMethod B ... 0 
After :public int generic.cglib.proxy.ConcreteClassNoInterface.getConcreteMethodB(int) 

可以看到,拦截器在调用被代理类方法前后都执行了print操作。

以上这篇Java CGLib动态代理机制(全面解析)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • maven profile实现多环境配置的示例

    maven profile实现多环境配置的示例

    这篇文章主要介绍了maven profile实现多环境配置的示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-01-01
  • java使用Hashtable过滤数组中重复值的方法

    java使用Hashtable过滤数组中重复值的方法

    这篇文章主要介绍了java使用Hashtable过滤数组中重复值的方法,涉及java数组遍历及过滤的相关技巧,需要的朋友可以参考下
    2016-08-08
  • Java中常用的设计模式之责任链模式详解

    Java中常用的设计模式之责任链模式详解

    这篇文章主要为大家详细介绍了Java中常用的设计模式之责任链模式,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-02-02
  • 详解Java实现设计模式之责任链模式

    详解Java实现设计模式之责任链模式

    责任链模式是一种行为设计模式,允许你将请求沿着处理链发送,然后处理者都可对其进行处理,完成后可以再将其传递给下一个处理者。下面将会举例说明什么是责任链模式,责任链模式该如何使用
    2021-06-06
  • JAVA获取本地MAC地址的方法

    JAVA获取本地MAC地址的方法

    这篇文章主要介绍了JAVA获取本地MAC地址的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-11-11
  • 使用SpringBoot配置https(SSL证书)

    使用SpringBoot配置https(SSL证书)

    这篇文章主要介绍了使用SpringBoot配置https(SSL证书),具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-12-12
  • springboot项目之相互依赖报错问题(基于idea)

    springboot项目之相互依赖报错问题(基于idea)

    这篇文章主要介绍了springboot项目之相互依赖报错问题(基于idea),具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-02-02
  • 浅析java 希尔排序(Shell)算法

    浅析java 希尔排序(Shell)算法

    这篇文章主要介绍了浅析java 希尔排序(Shell)算法的原理以及示例,需要的朋友可以参考下
    2015-02-02
  • Java ArrayDeque使用方法详解

    Java ArrayDeque使用方法详解

    这篇文章主要为大家详细介绍了Java ArrayDeque的使用方法,感兴趣的小伙伴们可以参考一下
    2016-03-03
  • Java方法覆盖重写实现原理解析

    Java方法覆盖重写实现原理解析

    这篇文章主要介绍了Java方法覆盖重写实现原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-12-12

最新评论