我是靠谱客的博主 机智蜻蜓,最近开发中收集的这篇文章主要介绍Dubbo SPI机制示例,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

 

1、dubbo SPI区别于JDK SPI,根据指定的key值,获取接口对应的实现,具体由下面支付示例展示:

订单支付接口,使用@SPI 注解标注,默认是阿里支付

package spi;

import com.alibaba.dubbo.common.extension.SPI;

/**
 * @Author: zhangshaolong001
 * @Date: 2020/4/15 11:18 AM
 * @Description:
 */
@SPI("aliPay")
public interface Order {
    String payType();
}

阿里支付实现:

package spi.extension;

import spi.Order;

/**
 * @Author: zhangshaolong001
 * @Date: 2020/4/15 11:20 AM
 * @Description:
 */
public class AlipayOrder implements Order {
    @Override
    public String payType() {
        return "支付宝支付";
    }
}

微信支付实现:

package spi.extension;

import spi.Order;

/**
 * @Author: zhangshaolong001
 * @Date: 2020/4/15 11:21 AM
 * @Description:
 */
public class WeChatOrder implements Order {
    @Override
    public String payType() {
        return "微信支付";
    }
}

 默认情况下,自适配实现

package spi.extension;

import com.alibaba.dubbo.common.extension.ExtensionLoader;
import org.springframework.util.StringUtils;
import spi.Order;

/**
 * @Author: zhangshaolong001
 * @Date: 2020/4/15 8:08 PM
 * @Description:
 */
public class AdaptiveOrder implements Order{
    private String payType;

    public void setPayType(String payType) {
        this.payType = payType;
    }

    @Override
    public String payType() {
        ExtensionLoader<Order> extensionLoader = ExtensionLoader.getExtensionLoader(Order.class);
        Order orderPay;
        if (StringUtils.isEmpty(this.payType)){
            orderPay = extensionLoader.getDefaultExtension();
        }else {
            orderPay = extensionLoader.getExtension(this.payType);
        }
        return orderPay.payType();
    }
}

配置文件:resources资源下,/META-INF/dubbo/internal文件夹下spi.Order命名的文件,也就是接口名:

aliPay=spi.extension.AlipayOrder
weChat=spi.extension.WeChatOrder

 

测试类

package spi;

import com.alibaba.dubbo.common.extension.ExtensionLoader;

/**
 * @Author: zhangshaolong001
 * @Date: 2020/4/15 11:22 AM
 * @Description:
 */
public class OrderPayTest {



    public static void main(String[] args) {
        ExtensionLoader<Order> extensionLoader = ExtensionLoader.getExtensionLoader(Order.class);
        Order orderPay = extensionLoader.getDefaultExtension();

        System.out.println(orderPay.payType());

        orderPay = extensionLoader.getExtension("weChat");
        System.out.println(orderPay.payType());
    }
}

 

 

以下代码来自 com.alibaba.dubbo.common.extension.ExtensionLoader

创建对象:

private T createExtension(String name) {
        //通过名称获取对应的类
        Class<?> clazz = getExtensionClasses().get(name);
        if (clazz == null) {
            throw findException(name);
        }
        try {
            T instance = (T) EXTENSION_INSTANCES.get(clazz);
            if (instance == null) {
                //通过反射创建类的对象实例
                EXTENSION_INSTANCES.putIfAbsent(clazz, clazz.newInstance());
                instance = (T) EXTENSION_INSTANCES.get(clazz);
            }
            //给对象注入属性
            injectExtension(instance);
            Set<Class<?>> wrapperClasses = cachedWrapperClasses;
            if (wrapperClasses != null && !wrapperClasses.isEmpty()) {
                for (Class<?> wrapperClass : wrapperClasses) {
                    instance = injectExtension((T) wrapperClass.getConstructor(type).newInstance(instance));
                }
            }
            return instance;
        } catch (Throwable t) {
            throw new IllegalStateException("Extension instance(name: " + name + ", class: " +
                    type + ")  could not be instantiated: " + t.getMessage(), t);
        }
    }


//注入属性
private T injectExtension(T instance) {
        try {
            if (objectFactory != null) {
                for (Method method : instance.getClass().getMethods()) {
                    //判断是否是set方法
                    if (method.getName().startsWith("set")
                            && method.getParameterTypes().length == 1
                            && Modifier.isPublic(method.getModifiers())) {
                        Class<?> pt = method.getParameterTypes()[0];
                        try {
                            String property = method.getName().length() > 3 ? method.getName().substring(3, 4).toLowerCase() + method.getName().substring(4) : "";
                            Object object = objectFactory.getExtension(pt, property);
                            if (object != null) {
                                method.invoke(instance, object);
                            }
                        } catch (Exception e) {
                            logger.error("fail to inject via method " + method.getName()
                                    + " of interface " + type.getName() + ": " + e.getMessage(), e);
                        }
                    }
                }
            }
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
        return instance;
    }

 

 

最后

以上就是机智蜻蜓为你收集整理的Dubbo SPI机制示例的全部内容,希望文章能够帮你解决Dubbo SPI机制示例所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(67)

评论列表共有 0 条评论

立即
投稿
返回
顶部