什么是动态代理

116 阅读2分钟

讲动态代理前,首先要讲解一下什么是代理。代理就是某件事情本来可以自己去做,但是交给别人去完成的这样一个过程。静态代理就是使用Java类的聚合方式进行代理操作的一个过程。而动态代理,则是通过InvocationHandler来完成对接口方法的代理。

使用动态代理,我们可以实现一些比较高级的代理过程,比如代理回调接口的实现。配置了@OnClick注解的方法,我们可以通过动态代理,本来应该要手写一个OnClickListener() {}的实现,在控件被点击的时候,调用OnClickListener() {}的onClick()方法,现在我们无需自己完成OnClickListener() {}的实现,而是交给InvocationHandler的实现类,帮助我们去调用相同参数的方法。一个类中方法那么多,怎么找到是哪个方法呢?通过配置注解来告诉我们,我们直接调用配置了该注解的方法就可以了。

InvocationHandler有一个重要的方法fun invoke(proxy: Any?, method: Method, args: Array): Any?。invoke()方法在它代理的接口被调用的时候拦截下来,然后做一些处理,我们可以用来改变调用,调我们想调的方法。

    Proxy.newProxyInstance(classLoader, interfaces, invocationHandler);

我们通过Proxy.newProxyInstance()方法来创建一个匿名的接口的实现类(代理类),三个参数分别是classLoader,通过字节码可以直接拿到,interfaces,要代理的所有接口,通过反射字节码可以拿到,invocationHandler,通过实现InvocationHandler接口然后传入。我们通过它竟然奇迹般地new出了一个接口的对象。然后我们通过调用这个代理类的方法,来完成被代理接口上的方法。

当然,动态代理不止InvocationHandler这一种,这是Retrofit的动态代理的实现方式,也是最有代表性的一种。