RPC实战与核心原理之动态代理了

动态代理
回顾
用来解决两个应用之间的通信,而网络则是两台l两台机器之间的“桥梁”,只有搭好桥梁才能把请求数据从一端传输到另一端,其中关键就是“可靠的传输”
背景
RPC的目标就是通过屏蔽调用细节,实现远程调用如同本地调用一样简单
在使用RPC时,一般的做法是先找服务提供方要接口,通过Maven或者其他工具把接口依赖到项目中,通过依赖注入的方式把接口注入项目中,然后在代码里面直接调用的方法
核心技术:动态代理
- RPC会自动给接口生成一个代理类,在项目中注入接口的时候,运行过程中实际绑定的是这个接口生成的代理类,在接口方法被调用的时候,实际上是被生成代理类拦截到了,这样就可以在生成的代理类中加入远程调用逻辑
动态代理
实现原理
/**
- 要代理的接口
 */
 public interface Hello {
 String say();
 }
/**
- 真实调用对象
 */
 public class RealHello {
public String invoke(){
    return "i'm proxy";
  }
}
/**
- JDK代理类生成
 */
 public class JDKProxy implements InvocationHandler {
 private Object target;
JDKProxy(Object target) {
    this.target = target;
  }
@Override
  public Object invoke(Object proxy, Method method, Object[] paramValues) {
    return ((RealHello)target).invoke();
  }
}
/**
- 测试例子
 */
 public class TestProxy {
public static void main(String[] args){
    // 构建代理器
    JDKProxy proxy = new JDKProxy(new RealHello());
    ClassLoader classLoader = ClassLoaderUtils.getCurrentClassLoader();
    // 把生成的代理类保存到文件
System.setProperty("sun.misc.ProxyGenerator.saveGeneratedFiles","true");
    // 生成代理类
    Hello test = (Hello) Proxy.newProxyInstance(classLoader, new Class[]{Hello.class}, proxy);
    // 方法调用
    System.out.println(test.say());
  }
}
- 给Hello接口生成一个动态代理类,并调用接口say()方法,但真实返回的值是来自RealHello里面的invoke()方法返回值
实现方法
- 在java领域(而我对java不熟),除了JDK默认的nvocationHandler能完成代理,还有很多第三方框架,如javassist、BYTE Buddy这样的框架也行
动态代理是一种具体的技术框架,那就会涉及到选型的问题,可从以下考虑
- 因为代理类是在运行中生成的,那么代理框架生成代理类的速度、生成代理类的字节码大小等等,都会影响到其性能——生成的字节码越小,运行所占资源就越小。
- 还有就是我们生成的代理类,是用于接口方法请求拦截的,所以每次调用接口方法的时候,都会执行生成的代理类,这时生成的代理类的执行效率就需要很高效。
- 最后一个是从我们的使用角度出发的,我们肯定希望选择一个使用起来很方便的代理类框架,比如我们可以考虑:API 设计是否好理解、社区活跃度、还有就是依赖复杂度等等。
 
                    
                     
                    
                 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号