• Java动态代理(三)——Cglib动态代理


    一、Cglib动态代理
    Cglib是一个优秀的动态代理框架,它的底层使用ASM在内存中动态的生成被代理类的子类,使用Cglib即使代理类没有实现任何接口也可以实现动态代理功能。而且,它的运行速度要远远快于JDK的Proxy动态代理。

    1.Cglib核心类

    • net.sf.cglib.proxy.Enhancer //主要的增强类
    • net.sf.cglib.proxy.MethodInterceptor //主要的方法拦截类,它是Callback接口的子接口,需要用户实现。这个接口只定义了一个方法
    • public Object intercept(Object object, java.lang.reflect.Method method,Object[] args, MethodProxy proxy) throws Throwable;//第一个参数是代理对像,第二和第三个参数分别是拦截的方法和方法的参数
    • net.sf.cglib.proxy.MethodProxy //JDK的java.lang.reflect.Method类的代理类,可以方便的实现对源对象方法的调用

    2.上篇PersonSerivice的Cglib代理实现(实现的前提是导入了Spring框架下的jar包)
    被代理的类:

    public class PersonServiceImp {
    private String name;
    private Integer age;
    
    public PersonServiceImp() {
    super();
    }
    
    public PersonServiceImp(String name, Integer age) {
    super();
    this.name = name;
    this.age = age;
    }
    
    public String getName() {
    System.out.println("---------getName------");
    return name;
    }
    
    public Integer getAge() {
    System.out.println("---------getAge--------");
    return age;
    }
    
    public void setName(String name) {
    this.name = name;
    }
    
    public void setAge(Integer age) {
    this.age = age;
    }
    }
    

    代理的类:

    import java.lang.reflect.Method;
    
    import org.springframework.cglib.proxy.MethodInterceptor;
    import org.springframework.cglib.proxy.MethodProxy;
    
    public class MyMethodInterceptor implements MethodInterceptor {
    
    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
    if ("getName".equals(method.getName())) {
    System.out.println("*********before*******");
    System.out.println("method:" + method);
    Object res = methodProxy.invokeSuper(obj, args);
    System.out.println("*********after********");
    return res;
    } else {
    Object res = methodProxy.invokeSuper(obj, args);
    return res;
    }
    }
    
    }
    

     

    测试:

    import org.springframework.cglib.proxy.Enhancer;
    
    public class CglibProxyTest {
    public static void main(String[] args) {
    PersonServiceImp person = new PersonServiceImp();
    Enhancer enhancer = new Enhancer();
    enhancer.setSuperclass(PersonServiceImp.class);
    enhancer.setCallback(new MyMethodInterceptor());
    person = (PersonServiceImp) enhancer.create();
    person.setName("jack");
    person.setAge(20);
    System.out.println(person.getClass().getName());
    System.out.println(person.getName());
    System.out.println(person.getAge());
    }
    }
    

      

    输出结果:

    二、Jdk动态道理和Cglib动态代理的区别
    1.JDK动态代理是利用反射机制实现的,在调用具体方法前调用InvokeHandler来处理。而Cglib动态代理是利用asm开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理。
    2.如果目标对象实现了接口,默认情况下会采用JDK的动态代理实现AOP,也可以强制使用CGLIB实现AOP;如果目标对象没有实现接口,必须采用CGLIB库,spring会自动在JDK动态代理和CGLIB之间转换。
    3.JDK动态代理只能对实现了接口的类生成代理,而不能针对类;CGLIB是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法, 因为是继承,所以该类或方法不要声明成final。

    4.使用CGLib实现动态代理,CGLib底层采用ASM字节码生成框架,使用字节码技术生成代理类,比使用Java反射效率要高。

  • 相关阅读:
    php操作apache服务器上的ftp
    win7配置ftp服务
    php访问远程服务器上的文件
    php操作ini配置文件
    php操作redis简单例子
    win7 32位安装php redis驱动
    mysql事务处理
    php使用PDO连接mysql数据库
    远程连接redis
    设置表格td宽度
  • 原文地址:https://www.cnblogs.com/ericz2j/p/10439407.html
Copyright © 2020-2023  润新知