doctorvian 2020-06-16


@SPI("alipay")
public interface PayService {
    void pay(double price);
}
public class AlipayService implements PayService {
    @Override
    public void pay(double price) {
        System.out.println("使用支付宝支付" + price +  "元");
    }
}
public class WechatPayService implements PayService {
    public void pay(double price) {
        System.out.println("使用微信支付" + price +  "元");
    }
}wechatPay = com.test.WechatPayService alipay = com.test.AlipayService
public static void main(String[] args) {
    ExtensionLoader<PayService> extensionLoader = ExtensionLoader.getExtensionLoader(PayService.class);
    PayService wechatPay = extensionLoader.getExtension("wechatPay");
    wechatPay.pay(20);
    PayService alipay = extensionLoader.getExtension("alipay");
    alipay.pay(20);
}@SPI("javassist") // 默认
public interface ProxyFactory {...}stub=com.alibaba.dubbo.rpc.proxy.wrapper.StubProxyFactoryWrapper jdk=com.alibaba.dubbo.rpc.proxy.jdk.JdkProxyFactory javassist=com.alibaba.dubbo.rpc.proxy.javassist.JavassistProxyFactory
public class ReferenceConfig<T> extends AbstractReferenceConfig {
    private static final ProxyFactory proxyFactory = ExtensionLoader.getExtensionLoader(ProxyFactory.class).getAdaptiveExtension();
    ...
    private T createProxy(Map<String, String> map) {
        ...
        // 该方法的最后一行
        return (T) proxyFactory.getProxy(invoker);
    }
     ...   
}public java.lang.Object getProxy(com.alibaba.dubbo.rpc.Invoker arg0) throws com.alibaba.dubbo.rpc.RpcException {
    if (arg0 == null) 
        throw new IllegalArgumentException("com.alibaba.dubbo.rpc.Invoker argument == null");
    if (arg0.getUrl() == null) 
        throw new IllegalArgumentException("com.alibaba.dubbo.rpc.Invoker argument getUrl() == null");
    com.alibaba.dubbo.common.URL url = arg0.getUrl();
    // 1.从 URL 中获取指定的SPI的扩展名称,proxy
    String extName = url.getParameter("proxy", "javassist");
    if(extName == null) 
        throw new IllegalStateException("Fail to get extension(com.alibaba.dubbo.rpc.ProxyFactory) name from url(" 
                                        + url.toString() + ") use keys([proxy])");
    // 2.通过 SPI 加载具体的实现类
    com.alibaba.dubbo.rpc.ProxyFactory extension = (com.alibaba.dubbo.rpc.ProxyFactory)ExtensionLoader
        .getExtensionLoader(com.alibaba.dubbo.rpc.ProxyFactory.class).getExtension(extName);
    // 3.调用目标方法
    return extension.getProxy(arg0);
}