dubbo 动态代理

ProxyFactory

//就是为了获取一个接口的代理类,例如获取一个远程接口的代理。
@SPI("javassist")
public interface ProxyFactory {
    
    @Adaptive({"proxy"})
     T getProxy(Invoker invoker) throws RpcException;

   //针对client端,创建接口的代理对象,例如DemoService的接口。
    @Adaptive({"proxy"})
     T getProxy(Invoker invoker, boolean generic) throws RpcException;

    //针对server端,将服务对象,如DemoServiceImpl包装成一个Invoker对象。
    @Adaptive({"proxy"})
     Invoker getInvoker(T proxy, Class type, URL url) throws RpcException;
}
复制代码

AbstractProxyFactory

/**
 * 主要是实现了 #getProxy(invoker)
 */
public abstract class AbstractProxyFactory implements ProxyFactory {

    @Override
    public  T getProxy(Invoker invoker) throws RpcException {
        return getProxy(invoker, false);
    }

    @Override
    public  T getProxy(Invoker invoker, boolean generic) 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 + 2] = ReflectUtils.forName(types[i]);
                }
            }
        }

        if (interfaces == null) {
            interfaces = new Class[]{invoker.getInterface(), EchoService.class};
        }

        if (!GenericService.class.isAssignableFrom(invoker.getInterface()) && generic) {
            int len = interfaces.length;
            Class[] temp = interfaces;
            interfaces = new Class[len + 1];
            System.arraycopy(temp, 0, interfaces, 0, len);
            interfaces[len] = com.alibaba.dubbo.rpc.service.GenericService.class;
        }

        return getProxy(invoker, interfaces);
    }
	//调用具体的实现
    public abstract  T getProxy(Invoker invoker, Class[] types);

}
复制代码

JavassistProxyFactory

public class JavassistProxyFactory extends AbstractProxyFactory {

    @Override
    public  T getProxy(Invoker invoker, Class[] interfaces) {
        return (T) Proxy.getProxy(interfaces)//这里产生字节码
                .newInstance(new InvokerInvocationHandler(invoker));
    }

}
复制代码

Proxy

//该方法主要是利用javasist生成代理类
public static Proxy getProxy(ClassLoader cl, Class... ics) {
      //...
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < ics.length; i++) {
            String itf = ics[i].getName();//获取接口名

            Class tmp = null;
            try {
                tmp = Class.forName(itf, false, cl);
            } catch (ClassNotFoundException e) {}

            sb.append(itf).append(';');
        }

        // use interface class name list as key.
        String key = sb.toString();

        // get cache by class loader.
        Map cache;
        synchronized (ProxyCacheMap) {
            cache = ProxyCacheMap.get(cl);
            if (cache == null) {
                cache = new HashMap();
                ProxyCacheMap.put(cl, cache);
            }
        }

        Proxy proxy = null;
        synchronized (cache) {
            do {
                Object value = cache.get(key);
                if (value instanceof Reference) {
                    proxy = (Proxy) ((Reference) value).get();
                    if (proxy != null)
                        return proxy;
                }

                if (value == PendingGenerationMarker) {
                    try {
                        cache.wait();
                    } catch (InterruptedException e) {
                    }
                } else {
                    cache.put(key, PendingGenerationMarker);
                    break;
                }
            }
            while (true);
        }

        long id = PROXY_CLASS_COUNTER.getAndIncrement();
        String pkg = null;
        ClassGenerator ccp = null, ccm = null;
        try {
            ccp = ClassGenerator.newInstance(cl);

            Set worked = new HashSet();
            List methods = new ArrayList();

            for (int i = 0; i < ics.length; i++) {
                if (!Modifier.isPublic(ics[i].getModifiers())) {
                    String npkg = ics[i].getPackage().getName();
                    if (pkg == null) {
                        pkg = npkg;
                    } else {
                        if (!pkg.equals(npkg))
                            throw new IllegalArgumentException("non-public interfaces from different packages");
                    }
                }
                ccp.addInterface(ics[i]);

                for (Method method : ics[i].getMethods()) {
                    String desc = ReflectUtils.getDesc(method);
                    if (worked.contains(desc))
                        continue;
                    worked.add(desc);

                    int ix = methods.size();
                    Class rt = method.getReturnType();
                    Class[] pts = method.getParameterTypes();

                    StringBuilder code = new StringBuilder("Object[] args = new Object[").append(pts.length).append("];");
                    for (int j = 0; j < pts.length; j++)
                        code.append(" args[").append(j).append("] = ($w)$").append(j + 1).append(";");
                    code.append(" Object ret = handler.invoke(this, methods[" + ix + "], args);");
                    if (!Void.TYPE.equals(rt))
                        code.append(" return ").append(asArgument(rt, "ret")).append(";");

                    methods.add(method);
                    ccp.addMethod(method.getName(), method.getModifiers(), rt, pts, method.getExceptionTypes(), code.toString());
                }
            }

            if (pkg == null)
                pkg = PACKAGE_NAME;

            //  接口的实现类
            String pcn = pkg + ".proxy" + id;
            ccp.setClassName(pcn);
            ccp.addField("public static java.lang.reflect.Method[] methods;");
            ccp.addField("private " + InvocationHandler.class.getName() + " handler;");
            ccp.addConstructor(Modifier.PUBLIC, new Class[]{InvocationHandler.class}, new Class[0], "handler=$1;");
            ccp.addDefaultConstructor();
            Class clazz = ccp.toClass();
            clazz.getField("methods").set(null, methods.toArray(new Method[0]));

            //  生成当前Proxy的子类,实现newInstance()方法
            String fcn = Proxy.class.getName() + id;
            ccm = ClassGenerator.newInstance(cl);
            ccm.setClassName(fcn);
            ccm.addDefaultConstructor();
            ccm.setSuperClass(Proxy.class);
            ccm.addMethod("public Object newInstance(" + InvocationHandler.class.getName() + " h){ return new " + pcn + "($1); }");
            Class pc = ccm.toClass();
            proxy = (Proxy) pc.newInstance();
        } //...省略部分代码
        }
        return proxy;
    }
 ///http://daveztong.github.io/2016/11/23/Dubbo%E5%AD%A6%E4%B9%A0-%E7%90%86%E8%A7%A3%E5%8A%A8%E6%80%81%E4%BB%A3%E7%90%86/
    abstract public Object newInstance(InvocationHandler handler);//newInstance方法大概是上面注释里的样子


 public class Proxy0 extends Proxy implements DC {

                public Object newInstance(InvocationHandler var1) {
                    return new proxy0(var1);  // (调下面的方法)返回的是DemoService的实例。
                }
                public Proxy0() {}
     }
 //给定一个接口比如DemoService,生成代理如下下
public class proxy0 implements DC, DemoService {
                public static Method[] methods;
                private InvocationHandler handler;

                public void sayHi(String var1) {
                        Object[] var2 = new Object[]{var1};
                  //这里去调用InvocationHandler逻辑
                        this.handler.invoke(this, methods[0], var2);
                }
                public proxy0() {
                    }
                public proxy0(InvocationHandler var1) {
                        this.handler = var1;
                }
     }
复制代码

到这里,javasist这种方式生成代理的方式流程基本梳理通了。

下面看下JDK这种方式创建的代理

JdkProxyFactory

public class JdkProxyFactory extends AbstractProxyFactory {

    @Override
    @SuppressWarnings("unchecked")
    public  T getProxy(Invoker invoker, Class[] interfaces) {
        return (T) Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), interfaces, new InvokerInvocationHandler(invoker));//常规方式,直接产生代理
    }
  
  //设置用jdk的方式
  // 服务引用


// 服务暴露

复制代码

好了。到底用哪种方式呢?这里就涉及到两种方案的性能对比了。

这里有duboo作者的测试结果。

http://javatar.iteye.com/blog/814426
复制代码

转载于:https://juejin.im/post/5beb89a16fb9a049f9121f1a

你可能感兴趣的:(dubbo 动态代理)