Dubbo原理实现之代理接口的定义
2018-03-22 21:21
579 查看
Dubbo有很多的实现采用了代码模式,Dubbo由代理工厂ProxyFactory对象创建代理对象。
ProxyFactory接口的定义如下:
@SPI("javassist") public interface ProxyFactory { /** * create proxy. * * @param invoker * @return proxy */ @Adaptive({Constants.PROXY_KEY}) <T> T getProxy(Invoker<T> invoker) throws RpcException; /** * create invoker. * * @param <T> * @param proxy * @param type * @param url * @return invoker */ @Adaptive({Constants.PROXY_KEY}) <T> Invoker<T> getInvoker(T proxy, Class<T> type, URL url) throws RpcException; }
@SPI指定默认使用javassist字节码技术来生成代理对象,接口定义了生成代理对象的方法getProxy, 入参是invoker对象,接口定义了获取invoker对象, invoker对象是个可执行对象,这里inovker对象的invoke方法其实执行的是根据url获取的方法对第一个入参的实体对象的调用,即:如果url的得知调用方法sayHello, 入参proxy为空Test对象实现test,那invoker.invoke()就是test.sayHello()。
代理工厂的实现类图如下:
AbstractProxyFactory: 代理工厂的公共抽象, 这里抽象实现主要是获取需要代理的接口,代理接口可以在设置在url中,key为interfaces, 如果是多个接口用逗号分隔, 如果没有在url中指定,获取invoke接口和EchoService接口
public <T> T getProxy(Invoker<T> invoker) throws RpcException { Class<?>[] interfaces = null; String config = invoker.getUrl().getParameter("interfaces"); if (config != null && config.length() > 0) { String[] types = Constants.COMMA_SPLIT_PATTERN.split(config); if (types != null && types.length > 0) { interfaces = new Class<?>[types.length + 2]; interfaces[0] = invoker.getInterface(); interfaces[1] = EchoService.class; for (int i = 0; i < types.length; i++) { interfaces[i + 1] = ReflectUtils.forName(types[i]); } } } if (interfaces == null) { interfaces = new Class<?>[]{invoker.getInterface(), EchoService.class}; } return getProxy(invoker, interfaces); }
JdkProxyFactory: 利用jdk动态代理来创建代理,实现比较简单
public <T> T getProxy(Invoker<T> invoker, Class<?>[] interfaces) { return (T) Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), interfaces, new InvokerInvocationHandler(invoker)); }
InvokerInvocationHandler是jdk动态代理创建一定要构建的参数,这里它的invoke方法只是简单的调用了invoker.invoke方法, Invoker在dubbo中代表一个可执行体,一切都向它靠拢。
获取invoker对象
public <T> Invoker<T> getInvoker(T proxy, Class<T> type, URL url) { return new AbstractProxyInvoker<T>(proxy, type, url) { @Override protected Object doInvoke(T proxy, String methodName, Class<?>[] parameterTypes, Object[] arguments) throws Throwable { Method method = proxy.getClass().getMethod(methodName, parameterTypes); return method.invoke(proxy, arguments); } }; }
这里创建的 Invoker对象,执行invoke方法,其实就是利用反射技术结合入参执行对应对象的对应方法。
相关文章推荐
- 4. Dubbo原理解析-代理之接口定义
- Dubbo原理解析-代理之接口定义
- 4. Dubbo原理解析-代理之接口定义
- Dubbo原理实现之使用Javassist字节码结束构建代理对象
- 23. Dubbo原理解析-编码解码之Codec2接口定义
- 22. Dubbo原理解析-编码解码之Serialization接口定义
- Springboot整合dubbo构建maven多模块项目(三) - 把server分为api(服务接口定义)和server(服务实现)两个子module
- 用nodejs做代理访问外部接口系统,如何实现带参数的post请求?
- java为数据结构中的映射定义了一个接口java.util.Map;它有四个实现类HashMap Hashtable LinkedHashMap 和TreeMap.
- Java 动态代理实现及原理
- JavaScript面向对象编程:类定义、继承、接口实现
- c++接口定义及实现举例
- Java动态代理原理及实现
- 实现AOP动态代理原理
- Effective C# 原则19:选择定义和实现接口而不是继承(译)
- 6. Dubbo原理解析-代理之Javassist生成的伪代码
- 1、实现接口的抽象类——适配器;2、代理公司的方法——功能更强大的包装类;3、接口的使用——工厂模式(高内聚低耦合)
- C++接口定义及实现举例
- Dubbo学习过程、使用经验分享及实现原理简单介绍
- 定义和实现接口