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); }