Cglib方法实现动态代理

  除了使用JDK方式产生动态代理外,Java还给我们提供了另外一种产生动态代理的方法,那就是使用cglib。

  cglib是这样实现动态代理的:

  · ①.针对类来实现代理

  · ②对指定目标类产生一个子类 ,通过方法拦截技术拦截所有父类方法的调用。

  ·

  cglib的实现机制与Java 动态代理不同,它是通过继承实现的 ,它也是动态创建了一个类,但这个类的父类是被代理的类,代理类重写了父类的所有public非final方法,改为调用Callback中的相关方法,在本例中,调用CglibProxy的intercept方法。

  具体实现步骤如下:

  1.我们先新建一个普通的Java项目,然后,在使用这个方法之前,我们需要给项目导入所需的jar包。

  cglib-nodep-2.2.jar

  2.建立被代理类

  package cglibProxy;

  public class Person {

  public void work(){

  System.out.println(工作中..);

  }

  }

  简单起见,我们这里只给Person类实现一个work()方法,用于模拟业务实现。

  3.接下来就是最重要的一点,建立代理类,代理类需要实现以下接口:

  interface MethodInterceptor{}

  这个接口需要我们导入jar包后才会出现,顾名思义,也就是方法拦截器。

  代理类的实现细节如下:

  package cglibProxy;

  import java.lang.reflect.Method;

  import net.sf.cglib.proxy.Enhancer;

  import net.sf.cglib.proxy.MethodInterceptor;

  import net.sf.cglib.proxy.MethodProxy;

  public class CglibProxy implements MethodInterceptor {

  private Enhancer enhancer = new Enhancer();

  public Object getProxy(Class clazz){

  //设置创建子类的类,即指定为哪个类产生代理类

  enhancer.setSuperclass(clazz);

  /*设置回调函数

  * setCallback设置被代理类的public非final方法被调用时的处理类

  * 这个例子中我们设置的方法为Person中的work()方法

  * 当work()方法被调用时,由该类进行处理

  * */

  enhancer.setCallback(this);

  //创建子类实例

  return enhancer.create();

  }

  /*

  * 作用:拦截所有目标类方法的调用

  * 参数:

  * 1. obj --目标类的实例对象

  * 2. method--目标方法的反射对象

  * 3. args --方法的参数

  * 4. proxy --代理类的实例对象

  * */

  @Override

  public Object intercept(Object obj, Method method, Object[] args,

  MethodProxy proxy) throws Throwable {

  System.out.println(代理类开始介入..);

  //代理类调用父类的方法

  proxy.invokeSuper(obj, args);

  System.out.println(代理类介入结束);

  return null;

  }

  }

  这里出现了一个比较少见的类Enhancer,查阅官方API,有这么一段注解:

  /*Generates dynamic subclasses to enable method interception.

  This class started as a substitute for the standard Dynamic Proxy

  support included with JDK 1.3, but one that allowed the proxies

  interfaces. The dynamically generated subclasses override

  the non-final methods of the superclass and have hooks which

  callback to user-defined interceptor implementations.*/

  翻译过来大概意思就是:

  /*生成动态子类以启用方法拦截。

  这个类开始替代了JDK 1.3中包含的标准动态代理支持,

  但是允许代理扩展一个具体的基类,以及实现接口。

  动态生成的子类覆盖超类的非最终方法,

  并具有回调到用户定义的拦截器实现的钩子。*/

  其实Enhancer类是CGLib中的一个字节码增强器,它可以方便的对你想要处理的类进行扩展。

  我们通过在代理类中聚合一个Enhancer类的一个实例对象,然后调用Enhancer实例对象的相应方法,对父类的调用方法进行拦截。

  代理类返回代理对象由getProxy()方法实现,其中:

  enhancer.setSuperclass(clazz);

  /*官方API对该类的注解如下:

  *Set the class which the generated class will extend.

  *翻译:

  *设置生成的类将要继承的类

  *这样比较难懂,从方法名中我们可以看出,这其实就是设置代理类的父类

  */

  与JDK动态代理不同,CglibProxy中没有被代理的对象,它通过MethodProxy类的实例对象proxy的invokeSuper方法调用被代理类的方法:

  proxy.invokeSuper(obj, args);

  但是,要注意的是,它不能这样调用被代理类的方法:

  proxy.invoke(obj, args);

  因为proxy是代理对象,调用这个方法还会调用到CglibProxy的intercept方法,造成死循环。

  3.最后,我们建立测试类

  package cglibProxy;

  public class Test {

  public static void main(String[] args) {

  //在main方法中,没有创建被代理的对象,创建的对象直接就是代理对象。

  CglibProxy proxy = new CglibProxy();

  //getProxy()方法返回代理方法产生的实例对象

  Person person = (Person)proxy.getProxy(Person.class);

  //代理对象调用wokr()方法

  person.work();

  }

  }

  运行结果:

  代理类开始介入..

  工作中..

  代理类介入结束

  动态代理是实现面向切面的编程(AOP – Aspect Oriented Programming)的基础,所以,了解动态代理的实现方法和机制是很有必要的,通过一个简单的实例,可以对动态代理有初步的认识,为以后的深入学习打下基础。

?

原文地址:https://www.cnblogs.com/qfjavabd/p/10109146.html

时间: 2024-11-08 21:22:07

Cglib方法实现动态代理的相关文章

【框架】[Spring] 基于Spring框架的Web应用演示(附带cglib工具进行动态代理)

转载请注明出处:http://blog.csdn.net/qq_26525215 本文源自[大学之旅_谙忆的博客] 前言: Spring也差不多学了Ioc控制反转和实现AOP技术的两种方式了,分享一个学习Spring,用来入门挺好的例子. 如果你是刚刚学习Spring,那么此实例应该可以很好的帮助你应用Spring到Web项目中. 里面的DAO层-提交数据库的事务我并没有使用Spring 的注解功能,而是用spring的AOP来实现的.这样更灵活,其实,框架为我们做的事越多,我们就越受框架的约束

CGlib和JDK动态代理

一.CGlib动态代理 JDK实现动态代理需要实现类通过接口定义业务方法,对于没有接口的类,如何实现动态代理呢,这就需要CGLib了.CGLib采用了非常底层的1:字节码技术,其原理是通过字节码技术为一个类创建子类,并在子类中采用2:方法拦截的技术拦截所有父类方法的调用,顺势织入横切逻辑.JDK动态代理与CGLib动态代理均是实现Spring AOP的基础. 字节码技术:参考:http://note.youdao.com/noteshare?id=13453e8d815d3102938a0288

性能优于JDK代理,CGLib如何实现动态代理

按照代理的创建时期,代理类可以分为两种. 静态代理:由程序员创建或特定工具自动生成源代码,再对其编译.在程序运行前,代理类的.class文件就已经存在了. 动态代理:在程序运行时,运用反射机制动态创建而成. 动态代理三种方式 动态代理实现有三种方式,jdk动态代理(基于接口),cglib动态代理(基于继承),javassist(hibernate中使用这种方式)实现动态代理. JDK实现动态代理需要实现类通过接口定义业务方法,对于没有接口的类,如何实现动态代理呢? 这就需要CGLib了. cgl

Cglib和jdk动态代理的区别

动态代理解决了方法之间的紧耦合, IOC解决了类与类之间的紧耦合! Cglib和jdk动态代理的区别? 1.Jdk动态代理:利用拦截器(必须实现InvocationHandler)加上反射机制生成一个代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理 2. Cglib动态代理:利用ASM框架,对代理对象类生成的class文件加载进来,通过修改其字节码生成子类来处理 什么时候用cglib什么时候用jdk动态代理? 1.目标对象生成了接口 默认用JDK动态代理 2.如果目标对象使

使用CGLIB包创建动态代理(2)(转)

当net.sf.cglib.proxy.MethodInterceptor做为所有代理方法的回调(callback)时,当对基于代理的方法调用时,在调用原对象的方法的之前会调用这个方法,如图3所示.第一个参数是代理对像,第二和第三个参数分别是拦截的方法和方法的参数.原来的方法可能通过使用java.lang.reflect.Method对象的一般反射调用,或者使用net.sf.cglib.proxy.MethodProxy对象调用.net.sf.cglib.proxy.MethodProxy通常被

CGLib动态代理原理及实现

JDK实现动态代理需要实现类通过接口定义业务方法,对于没有接口的类,如何实现动态代理呢,这就需要CGLib了.CGLib采用了非常底层的字节码技术,其原理是通过字节码技术为一个类创建子类,并在子类中采用方法拦截的技术拦截所有父类方法的调用,顺势织入横切逻辑.JDK动态代理与CGLib动态代理均是实现Spring AOP的基础. 简单的实现举例: 这是一个需要被代理的类,也就是父类,通过字节码技术创建这个类的子类,实现动态代理. [java] view plain copy public clas

JDK动态代理和CGLIB动态代理+源码下载

在上一篇文章-java代理详解讲解实现机制,一种是继承另外一种是组合,而且通过做实现也证明使用组合的方式更加的灵活.之后提到了代理的两种种类,一种是静态代理,另外一种是动态代理.上一篇文件中着重介绍的是静态代理(相对于动态代理很容易理解).这一片文章就接着介绍动态代理. 动态代理实现的最终效果:通过以一个统一的方式实现对任意的接口/类的代理.相比较静态代理而言,我们可以不用再无限制的增加代理类,不用再写许多重复的代码.很符合面向对象设计原则中的"开闭原则":对修改关闭,对扩展开放. 动

java 静态代理 JDK动态代理 Cglib动态代理

下面以一个简单的银行账户为例讲述讲述动态代理. 设计一个银行账户类,包含用户的账户余额,实现查询和更新余额功能 这个系统用了一段时间,有客户要求对账说账户余额给弄错了?因为上面没有存取款记录,最后银行不认账,客户收到了损失.银行为了避免这种现象再次发生,决定对这个系统进行修改,但是因为bankAccount太过复杂,希望在不修改bankAccount的情况下,增加日志功能. 静态代理 使用静态代理解决上面的问题. 银行要求所有模块都需要添加日志功能,这对苦逼的程序员来说真的是一个不小的工作量啊,

动态代理(CGLIB实现)

CGLIB(Code Generation Library)是一个开源项目.可以直接对类进行增强,而不需要像JDK的动态代理,需要增强的类必须实现某接口 在使用Spring框架时,因为Spring框架中core包中引入了cglib所以如果想通过cglib来实现动态代理,不需要专门的导cglib的jar包. 创建代理工厂时,必须得实现MethodInterceptor接口,因为通过cglib创建的代理对象在调方法时会默认执行intercept方法,通过该方法增加目标对象方法. public cla