您当前的位置: 首页 > 
  • 2浏览

    0关注

    674博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

动态代理

沙漠一只雕得儿得儿 发布时间:2021-03-24 20:52:41 ,浏览量:2

什么情况下使用动态代理?

1、需要对较难修改的类方法进行功能增加。 2、RPC即远程过程调用,通过动态代理的建立一个中间人进行通信。 3、实现切面编程(AOP)可以采用动态代理的机制来实现。

说下生活中对应的场景,明星接通告 一般商家要找明星做活动,是要先找到他的经纪人,然后经纪人去负责一些琐碎的或者运营方面的事情,而明星只需要做具体的活动相关事情就可以了。这里经纪人的作用就是作为了一个代理。

静态代理

首先是静态代理,上代码

 /**
     * 首先声明一个接口,用于工作的接口
     */
    public interface IStarDao {
        void dowork();
    }

    /**
     * 明星工作类
     * 主要为演戏
     */
    public class SuperStarDao implements IStarDao {

        @Override
        public void dowork() {
            //演戏工作
        }
    }

    /**
     * 经纪人代理类
     * 主要是负责接活,并且安排明星工作,以及后续宣传工作
     */
    public class StarbrokerDaoProxy implements IStarDao {

        private IStarDao starDao;

        public StarbrokerDaoProxy(IStarDao starDao) {
            this.starDao = starDao;
        }

        @Override
        public void dowork() {
            /*--接活--*/
            starDao.dowork();//明星工作
            /*--宣传工作--*/
        }
    }

ok,至此明星和经纪人已经创建完毕,接下来就是怎么去操作,首先找到具体的明星,然后找到对应的经纪人,也就是代理类,从而完成所有工作

    public void main() {
        SuperStarDao starDao = new SuperStarDao();
        StarbrokerDaoProxy proxy = new StarbrokerDaoProxy(starDao);
        proxy.dowork();
    }
动态代理

动态代理的特点是不需要提前创建代理对象,而是利用反射机制在运行时创建代理类,从而动态实现代理功能 也就是说,这里的明星不需要具体的经纪人了。有活动的时候,可以创建一个经纪人,可以是自己,可以是家人,然后完成原本代理的一些工作,见代码

    public void main() {
        final IStarDao starDao = new SuperStarDao();

        IStarDao proxy = (IStarDao) Proxy.newProxyInstance(
                starDao.getClass().getClassLoader(),
                starDao.getClass().getInterfaces(),
                new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        /*--接活--*/
                        Object returnValue = method.invoke(starDao, args);//明星工作
                        /*--宣传工作--*/
                        return returnValue;
                    }
                });

        proxy.dowork();
    }
在Android中的应用

Retrofit,想必大家都很熟悉,retrofit其实核心内容就是用了动态代理。

想想retrofit是怎么工作的?在interface里面写上需要配置的请求方法,并添加一些注解 然后创建出interface的实例,就可以直接调用方法进行网络请求了。 看看代码:

public interface ApiService {
   	@POST(RetrofitHelper.APP_V1 + "/banner")
    Observable getBanners();
}
 
ApiService mService = new Retrofit.Builder().baseUrl("").build().create(ApiService.class);

service.getBanners().enqueue(callback);

我们只是写了ApiService接口和接口下面的getBanners方法,然后就可以进行网络请求。 所以retrofit是代替我们写了网络请求的具体逻辑,也就是完成了代理的这样一个作用。

具体怎么代理的呢? 奥秘主要就在这个 create(ApiService.class)方法 里面,看看源码:

  public  T create(final Class service) {
    return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class[] { service },
        new InvocationHandler() {
          private final Platform platform = Platform.get();
          @Override public Object invoke(Object proxy, Method method, @Nullable Object[] args)
              throws Throwable {
            ServiceMethod serviceMethod =
                (ServiceMethod) loadServiceMethod(method);
            OkHttpCall okHttpCall = new OkHttpCall(serviceMethod, args);
            return serviceMethod.callAdapter.adapt(okHttpCall);
          }
        });
  }

看到这个newProxyInstance方法了吧,这就是创建动态代理类的方法。 invoke方法里面就是具体去拆解 接口里面方法的一些参数,然后完成网络请求的整个过程了,也就是代理帮你做的一些事情。

这里顺便就简单说下这些源码干了什么事,也方便大家自己研究源码

  • loadServiceMethod 主要是读取接口里面每个方法的注解,参数等等
  • new OkHttpCall 主要是调用okhttp的一些方法,发起一些网络请求
  • adapt(okHttpCall) 主要是转换OkHttpCall对象,并且切换到主线程
关注
打赏
1657159701
查看更多评论
立即登录/注册

微信扫码登录

0.1177s