美文网首页
cglib动态代理和retrofit

cglib动态代理和retrofit

作者: 勇敢地追 | 来源:发表于2019-09-28 16:29 被阅读0次

1.cglib介绍

代理提供了一个可扩展的机制来控制被代理对象的访问,其实说白了就是在对象访问的时候加了一层封装。jdk动态代理使用起来非常简单,但是有个明显的缺点:需要目标对象实现一个或多个接口。假如你想代理没有接口的类呢?可以使用CGLIB库。
cglib有个最重要的接口MethodInterceptor,这个接口只有一个方法:

public Object intercept(Object object, java.lang.reflect.Method method, Object[] args, MethodProxy proxy) throws Throwable;

MethodInterceptor.intercept方法的第一个参数是代理对象,第二个、第三个参数分别是被拦截的方法和方法的参数。
如果想调用被代理对象的原始方法,可以通过使用Method对象来反射调用,或者使用MethodProxy对象。我们通常使用MethodProxy因为它更快。
在intercept方法中,自定义代码可以在原始方法调用前或调用后注入。

2.简单Demo

(记得添加依赖 cglib的github地址有)

  • 1.实现一个业务类,注意,这个业务类并没有实现任何接口
public class RetrofitService {
    public void loadData(String params) {
        System.out.println("RetrofitService loadData " + params);
    }
}
  • 2.自定义MethodInterceptor
public class RetrofitMethodInterceptor implements MethodInterceptor {

    @Override
    public Object intercept(Object sub, Method arg1, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("======插入前置通知======");
        if(arg1.getName().equals("loadData") && objects[0] instanceof String) {
            objects[0] = "aaaaaaaaaaa";
        }
        Object object = methodProxy.invokeSuper(sub, objects);
        System.out.println("======插入后者通知======");
        return object;
    }
}
  • 3.测试代码
public class Main {

    public static void main(String[] args) {
        // 代理类class文件存入本地磁盘方便我们反编译查看源码
        System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "../");
        // 通过CGLIB动态代理获取代理对象的过程
        Enhancer enhancer = new Enhancer();
        // 设置enhancer对象的父类
        enhancer.setSuperclass(RetrofitService.class);
        // 设置enhancer的回调对象
        enhancer.setCallback(new RetrofitMethodInterceptor());
        // 创建代理对象
        RetrofitService proxy = (RetrofitService) enhancer.create();
        // 通过代理对象调用目标方法
        proxy.loadData("lalalalalala");
    }
}
  • 4.查看代理类
    加了System.setProperty这句话会在对应的目录下生成对应的包名,里面就会有对应的代理类,里面一共有三个文件,我们暂时只需要这个 RetrofitService$$EnhancerByCGLIB$$158ba096
public final void loadData(final String s) {
        MethodInterceptor cglib$CALLBACK_2;
        MethodInterceptor cglib$CALLBACK_0;
        if ((cglib$CALLBACK_0 = (cglib$CALLBACK_2 = this.CGLIB$CALLBACK_0)) == null) {
            CGLIB$BIND_CALLBACKS(this);
            cglib$CALLBACK_2 = (cglib$CALLBACK_0 = this.CGLIB$CALLBACK_0);
        }
        if (cglib$CALLBACK_0 != null) {
            cglib$CALLBACK_2.intercept((Object)this, RetrofitService$$EnhancerByCGLIB$$158ba096.CGLIB$loadData$0$Method, new Object[] { s }, RetrofitService$$EnhancerByCGLIB$$158ba096.CGLIB$loadData$0$Proxy);
            return;
        }
        super.loadData(s);
    }

可以看到会调用我们自定义的intercept.整个过程其实和jdk动态代理类似

https://blog.csdn.net/yhl_jxy/article/details/80633194

http://ifeve.com/cglib-desc/

相关文章

  • cglib动态代理和retrofit

    1.cglib介绍 代理提供了一个可扩展的机制来控制被代理对象的访问,其实说白了就是在对象访问的时候加了一层封装。...

  • Java面试之Java基础下册(含答案)

    15.动态代理与cglib实现的区别。 动态代理有两种实现方式,分别是:jdk动态代理和cglib动态代理 jdk...

  • 源码解析--JDK动态代理

    动态代理的两种方式JDK动态代理和cglib动态代理在上一篇中动态代理jdk和cglib的区别已经通过实例做了比较...

  • JDK和CGLIB动态代理区别

    JDK和CGLIB动态代理区别 一 JDK和CGLIB动态代理原理1、JDK动态代理利用拦截器(拦截器必须实现In...

  • java动态代理

    目前动态代理主要有两种形式,jdk和cglib代理,其中动态代理是基于接口的代理,而cglib是基于类的动态代理。...

  • Spring的AOP原理分析

    一 动态代理 动态代理分为JDK动态代理和CGLIB动态代理 jdk动态代理 被代理类(目标类)和代理类必须实现同...

  • java动态代理

    目录: 简介 jdk动态代理 cglib动态代理 jdk动态代理与cglib的区别 应用spring的aop 简介...

  • Java下的两种代理

    代理 JDK动态代理 CGLIB动态代理 CGLIB(Code Generation Library)是一个基于A...

  • 设计模式之代理模式

    代理分为静态代理和动态代理。 动态代理又包括基于JDK的动态代理、基于CGlib 的动态代理、基于Aspectj实...

  • Java高级主题(五)——动态代理

    代理可以分为静态代理、动态代理,动态代理又可以分为 jvm的动态代理 和 cglib的动态代理。像spring框架...

网友评论

      本文标题:cglib动态代理和retrofit

      本文链接:https://www.haomeiwen.com/subject/mbgductx.html