美文网首页框架【库】
retrofit拆解 - 动态代理

retrofit拆解 - 动态代理

作者: 最最最最醉人 | 来源:发表于2016-10-11 14:28 被阅读1490次

    引言

    在使用Retrofit的时候,我们在通过Builder模式获取到Retrofit对象之后,需要通过create方法来获取到接口对象

    public interface Api {
        @GET("api/data/福利/{pageCount}/{pageIndex}")
        Call<BaseModel<ArrayList<Benefit>>> defaultBenefits(
                @Path("pageCount") int pageCount,
                @Path("pageIndex") int pageIndex
        );
    
        @GET("api/data/福利/{pageCount}/{pageIndex}")
        Observable<BaseModel<ArrayList<Benefit>>> rxBenefits(
                @Path("pageCount") int pageCount,
                @Path("pageIndex") int pageIndex
        );
    }
    
    Api api = retrofit.create(Api.class);
    

    如果仔细一看好像不对啊,为什么接口没有实现,就获取到实例了呢?那么retrofit如何实现我们指定接口的实例呢?
    其实原理是:动态代理。

    初始动态代理

    动态代理是代理模式中的一种,动态代理也算是java的一个特色。
    Java动态代理类位于Java.lang.reflect包下,一般主要涉及到以下两个类:

    1. Interface InvocationHandler:该接口中仅定义了一个方法Object:invoke(Object obj,Method method,Object[] args)。在实际使用时,第一个参数obj一般是指代理类,method是被代理的方法,args为该方法的参数数组。这个抽象方法在代理类中动态实现。

    2. Proxy:该类即为动态代理类。

    我们先看一个例子,来对动态代理有一个简单的了解

    public interface IAPI {
        @Deprecated
        public void getData(int pageCount, int pageIndex);
    }
    
    public static void main(String[] args) {
        IAPI iApi = (IAPI) Proxy.newProxyInstance(IAPI.class.getClassLoader(), new Class<?>[]{IAPI.class}, new InvocationHandler() {
            
            @Override
            public Object invoke(Object proxy, Method method, Object[] args)
                    throws Throwable {
                
                Integer pageCount = (Integer) args[0];
                Integer pageIndex = (Integer) args[1];
                System.out.println("参数: " + pageCount + "," + pageIndex);
                System.out.println("方法名: " + method.getName());
                
                Annotation[] annotations = method.getAnnotations();
                System.out.println("注解:" + annotations[0].toString());
                
                return null;
            }
        });
        iApi.getData(5, 8);
    }
    
    // 打印结果
    参数: 5,8
    方法名: getData
    注解:@java.lang.Deprecated()
    

    可以看出,我们通过Proxy.newProxyInstance产生的代理类,当调用接口的方法时,都会调用InvocationHandler#invoke方法,在这个方法中可以获取到传入的参数和注解,以及方法名等信息。

    同理,retrofit同样可以通过这种动态代理的方法,获取到接口里的注解信息,参数。

    Retrofit中的动态代理

    Retrofit.create()

    通过观察也就很容易理解,retrofit是如何为我们接口生成实例的了。

    相关参考链接

    Retrofit2 完全解析 探索与okhttp之间的关系
    别人家SDK中的设计模式--Android Retrofit库源码解读
    Retrofit分析-漂亮的解耦套路
    独特的架构方式,Retrofit源码简析。

    相关文章

      网友评论

        本文标题:retrofit拆解 - 动态代理

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