cglib

参考:http://blog.csdn.net/zhoudaxia/article/details/30591941

 

<!-- https://mvnrepository.com/artifact/cglib/cglib -->
<dependency>
    <groupId>cglib</groupId>
    <artifactId>cglib</artifactId>
    <version>3.2.0</version>
</dependency>

 

都是copy过来的。 

CGlib是一个强大的,高性能,高质量的Code生成类库。它可以在运行期扩展Java类与实现Java接口。其底层是通过小而快的字节码处理框架ASM(http://forge.ow2.org/projects/asm,使用BSD License)来转换字节码并生成新的类。大部分功能实际上是asm所提供的,CGlib只是封装了asm,简化了asm的操作,实现了在运行期动态生成新的class。

  CGlib被许多AOP的框架使用,例如Spring AOP和dynaop,为他们提供方法的interception(拦截);最流行的OR Mapping工具hibernate也使用CGLIB来代理单端single-ended(多对一和一对一)关联(对集合的延迟抓取,是采用其他机制实现的);EasyMock和jMock是通过使用模仿(moke)对象来测试java代码的包,它们都通过使用CGLIB来为那些没有接口的类创建模仿(moke)对象。

  CGLIB包的基本代码很少,但学起来有一定的困难,主要是缺少文档,API描述过于简单,这也是开源软件的一个不足之处。目前CGLIB的版本是cglib-2.2.jar,主要由一下部分组成:
  (1)net.sf.cglib.core:底层字节码处理类,他们大部分与ASM有关系。
  (2)net.sf.cglib.transform:编译期或运行期类和类文件的转换。
  (3)net.sf.cglib.proxy :实现创建代理和方法拦截器的类。
  (4)net.sf.cglib.reflect :实现快速反射和C#风格代理的类。
  (5)net.sf.cglib.util:集合排序工具类。
  (6)net.sf.cglib.beans:JavaBean相关的工具类。

  CGLIB包是在ASM之上的一个高级别的层。对代理那些没有实现接口的类非常有用。本质上,它是通过动态的生成一个子类去覆盖所要代理类的不是final的方法,并设置好callback,则原有类的每个方法调用就会转变成调用用户定义的拦截方法(interceptors),这比JDK动态代理方法快多了。可见,Cglib的原理是对指定的目标类动态生成一个子类,并覆盖其中方法实现增强,但因为采用的是继承,所以不能对final修饰的类和final方法进行代理。

 

public class HelloWorld {

    public void sayHelloWorld() {
        System.out.println("HelloWorld!");
    }

}

 

 

 

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

/**
 * @author lishupeng
 * @Description
 * @Date 2017/12/11 13:53
 */
public class CglibProxy implements MethodInterceptor {
    //要代理的原始对象
    private Object obj;

    public Object createProxy(Object target) {
        this.obj = target;
        Enhancer enhancer = new Enhancer();
        // 设置要代理的目标类,以扩展它的功能
        enhancer.setSuperclass(this.obj.getClass());
        // 设置单一回调对象,在回调中拦截对目标方法的调用
        enhancer.setCallback(this);
        //设置类装载器
        enhancer.setClassLoader(target.getClass().getClassLoader());
        //创建代理对象
        return enhancer.create();
    }

    /**
     * 回调方法:在代理实例上拦截并处理目标方法的调用,返回结果
     *
     * @param proxy       代理类
     * @param method      被代理的方法
     * @param params      该方法的参数数组
     * @param methodProxy
     */
    @Override
    public Object intercept(Object proxy, Method method, Object[] params,
                            MethodProxy methodProxy) throws Throwable {
        Object result = null;
        // 调用之前
        doBefore();
        // 调用目标方法,用methodProxy,
        // 而不是原始的method,以提高性能
        result = methodProxy.invokeSuper(proxy, params);
        // 调用之后
        doAfter();
        return result;
    }

    private void doBefore() {
        System.out.println("before method invoke");
    }

    private void doAfter() {
        System.out.println("after method invoke");
    }

    public static void main(String[] args) {
        CglibProxy cglibProxy = new CglibProxy();
        HelloWorld hw = (HelloWorld) cglibProxy.createProxy(new HelloWorld());
        hw.sayHelloWorld();
    }
}

 

posted on 2017-12-11 13:50  ..小树苗  阅读(174)  评论(0编辑  收藏  举报

导航