Dubbo 源码阅读(三)getAdaptiveExtension

实际工作中,我们希望实例能懒加载,或者运行期自动选择

注解 @Adaptive 能解决这个选择问题

  • 注解在实例类上时,直接选此类为适配类(一个接口只允许一个类标记)
  • 注解在接口方法上时,只为此方法生成代理逻辑(方法必须有参数为url或者参数有返回url的方法)
/**
 * 各个实现类上面没有@Adaptive
 * SPI上有注解@SPI("b")
 * URL中有具体的值info.service=a,
 * 则以URL为准,选择A实现
 */
@Test
public void test1(){
    ExtensionLoader<InfoService> loader = ExtensionLoader.getExtensionLoader(InfoService.class);
    InfoService adaptiveExtension = loader.getAdaptiveExtension();
                                                //接口 InfoService
    URL url = URL.valueOf("test://localhost/test?info.service=a");
    System.out.println(adaptiveExtension.passInfo("james", url));
}

/**
 * 各个实现类上面没有@Adaptive
 * 接口方法中加上注解@Adaptive({"InfoService"}),
 * URL中有具体的值InfoService=c,
 * 则以URL中的InfoService参数为准,选择C实现
 */
@Test
public void test2(){
    ExtensionLoader<InfoService> loader = ExtensionLoader.getExtensionLoader(InfoService.class);
    InfoService adaptiveExtension = loader.getAdaptiveExtension();
    URL url = URL.valueOf("test://localhost/test?info.service=a&InfoService=c");
    System.out.println(adaptiveExtension.passInfo("james", url));
}

跟 getAdaptiveExtension:

 public T getAdaptiveExtension() {
    Object instance = cachedAdaptiveInstance.get();
    if (instance == null) {
        if (createAdaptiveInstanceError == null) {
            synchronized (cachedAdaptiveInstance) {
                instance = cachedAdaptiveInstance.get();
                if (instance == null) {
                    try {
                        instance = createAdaptiveExtension();
                        cachedAdaptiveInstance.set(instance);
                    } catch (Throwable t) {
                        createAdaptiveInstanceError = t;
                        throw new IllegalStateException("fail to create adaptive instance: " + t.toString(), t);
                    }
                }
            }
        } else {
            throw new IllegalStateException("fail to create adaptive instance: " + createAdaptiveInstanceError.toString(), createAdaptiveInstanceError);
        }
    }

    return (T) instance;
}

跟 createAdaptiveExtension:

private T createAdaptiveExtension() {
   try {
       return injectExtension((T) getAdaptiveExtensionClass().newInstance());
   } catch (Exception e) {
       throw new IllegalStateException("Can not create adaptive extension " + type + ", cause: " + e.getMessage(), e);
   }
}

跟 getAdaptiveExtensionClass:

private Class<?> getAdaptiveExtensionClass() {
    getExtensionClasses();
    if (cachedAdaptiveClass != null) {
        return cachedAdaptiveClass;
    }
    return cachedAdaptiveClass = createAdaptiveExtensionClass();
}

跟 createAdaptiveExtensionClass:

private Class<?> createAdaptiveExtensionClass() {
    //构建Class内容的字符串
    String code = createAdaptiveExtensionClassCode();
    ClassLoader classLoader = findClassLoader();
    com.alibaba.dubbo.common.compiler.Compiler compiler = ExtensionLoader.getExtensionLoader(com.alibaba.dubbo.common.compiler.Compiler.class).getAdaptiveExtension();
    return compiler.compile(code, classLoader);
}
发布了185 篇原创文章 · 获赞 271 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/weixin_44367006/article/details/105224903
今日推荐