实现一个Cglib代理Demo

Cglib动态代理采用的是创建目标类的子类的方式。优点:不用实现额外接口,只操作我们关心类,高性能。

package jesse.test;

import java.lang.reflect.Method;

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

class Father{
    public void sayHello(){
        System.out.println("this is father");
    }
}

interface Person{
    void speak();
    void walk();
}

class Student extends Father implements Person{
    public void study(){
        System.out.println("i am student.");
    }
    
    @Override
    public void speak() {
        System.out.println("i am student ,i can speak");
    }

    @Override
    public void walk() {
        System.out.println("i am student ,i can walk");        
    }
}

class MyMethodInterceptor implements MethodInterceptor{
    @Override
    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;
    }
    
}

public class MyCglibProxy {
    public static void main(String[] args) {
        //可以指定 CGLIB 将动态生成的代理类保存至指定的磁盘路径下
        //System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY,"本地磁盘路径");
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(Student.class);
        enhancer.setCallback(new MyMethodInterceptor());
        Student student = (Student)enhancer.create();
        student.sayHello();
        student.speak();
        student.walk();
        student.study();
    }
    
}
/**
 * 就是只能为接口中的方法完成代理,而委托类自己的方法或者父类中的方法都不可能被代理。
 * CGLIB 应运而生,它是一个高性能的,底层基于 ASM 框架的一个代码生成框架,它完美的解决了 JDK 版本的
 * 动态代理只能为接口方法代理的单一性不足问题
 * 
 * Student 是我们需要代理的委托类型,结果生成的代理类就直接继承了委托类。
 * 这一个小设计就完美的解决了 JDK 动态代理那个单一代理的缺陷,继承了委托类,就可以反射出委托类接口中的所有方法,
 * 父类中的所有方法,自身定义的所有方法,完成这些方法的代理就完成了对委托类所有方法的代理。
 * 
 * 说明:cglib生成代理是通过字节码生成的子类作为代理类,因此不能对private final方法代理;
 * 
 * 比较:
 * CGLib动态代理创建代理实例速度慢,但是运行速度快;JDK动态代理创建实例速度快,但是运行速度慢。如果实例是单例的,
 * 推荐使用CGLib方式动态代理,反之则使用JDK方式进行动态代理。Spring的实例默认是单例,所以这时候使用CGLib性能高。 
 * 
 */

  

<!-- cglib -->
<dependency>
      <groupId>cglib</groupId>
      <artifactId>cglib</artifactId>
      <version>3.2.5</version>
</dependency>

  

posted @ 2018-11-15 17:50  一心行走  阅读(1083)  评论(0编辑  收藏  举报