java 中SPI和Dubbo中SPI的区别

java 中SPI和Dubbo中SPI的区别,第1张

今天分享两者区别:

1、原理方面:

java是一次性加载完毕,浪费资源。

Dubbo是对javaSPI的扩展,以键值对的形式存在,用到哪个实现类取哪一个,而且可以分组,默认注解配置等方式。

2、代码示例:

1)javaspi示例:

定义一个接口:


public interface Log {
    void debug();
}

定义两个实现类:

public class Log4j implements Log {
    @Override
    public void debug() {
        System.out.println("==========log4j");
    }
}


public class Logback implements Log {
    @Override
    public void debug() {
        System.out.println("========logback");
    }
}


配置文件配置:

代码:

cn.enjoy.javaspi.Log4j
cn.enjoy.javaspi.Logback

 测试获取代码:

public class MyTest {
    public static void main(String[] args) {
        //这个代码就会加载META-INF/services 下面的log接口的文件中的所有类
        ServiceLoader all = ServiceLoader.load(Log.class);
        Iterator iterator = all.iterator();
        //这个地方需要挨个遍历去区分每一个实例的不同
        while (iterator.hasNext()) {
            Log next = iterator.next();
            if(next instanceof Log4j) {
                next.debug();
            }
        }
    }
}

2)dubbospi代码示例:

定义接口一个:

//这个注解一定要
@SPI("spring")
public interface ActivateApi {
    
    String todo(String param);
}

定义实现类N个:

import com.alibaba.dubbo.common.extension.Activate;
import com.alibaba.dubbo.common.extension.Adaptive;

@Adaptive
@Activate(order = 2,group = {"dubbo"})
public class DubboActivate implements ActivateApi {
    @Override
    public String todo(String param) {
        return param;
    }
}


@Activate(group = {"mybatis","mybatis1"})
public class MyBatisActivate implements ActivateApi {
    @Override
    public String todo(String param) {
        return param;
    }
}


@Activate(group = {"rabbitmq"})
public class RabbitmqActivate implements ActivateApi {
    @Override
    public String todo(String param) {
        return param;
    }
}

@Activate(group = {"rabbitmq"})
public class RabbitmqActivate1 implements ActivateApi {
    @Override
    public String todo(String param) {
        return param;
    }
}


@Activate(value = {"value1"},group = {"rabbitmq"})
public class RabbitmqActivate2 implements ActivateApi {
    @Override
    public String todo(String param) {
        return param;
    }
}


@Activate(group = {"spring"})
public class SpringActivate implements ActivateApi {
    @Override
    public String todo(String param) {
        return param;
    }
}

@Activate(order = 1,group = {"springcloud"})
public class SpringCloudActivate implements ActivateApi {
    @Override
    public String todo(String param) {
        return param;
    }
}

配置文件配置:

 核心配置:

dubbo=cn.enjoy.dubbospi.DubboActivate
mybatis=cn.enjoy.dubbospi.MyBatisActivate
rabbitmq=cn.enjoy.dubbospi.RabbitmqActivate
rabbitmq1=cn.enjoy.dubbospi.RabbitmqActivate1
rabbitmq2=cn.enjoy.dubbospi.RabbitmqActivate2
spring=cn.enjoy.dubbospi.SpringActivate
springcloud=cn.enjoy.dubbospi.SpringCloudActivate

 

 测试类:

import cn.nandao.dubbospi.ActivateApi;
import com.alibaba.dubbo.common.URL;
import com.alibaba.dubbo.common.extension.ExtensionLoader;
import com.alibaba.dubbo.registry.Registry;
import com.alibaba.dubbo.registry.RegistryFactory;
import com.alibaba.dubbo.rpc.Protocol;
import com.alibaba.dubbo.rpc.ProxyFactory;
import org.junit.Test;

import java.util.List;
 
public class SpiTest {

    @Test
    public void adaptive() {
        //@Adaptive 有单独的api那实现了这个注解的实现类
        ActivateApi adaptiveExtension = ExtensionLoader.getExtensionLoader(ActivateApi.class).getAdaptiveExtension();
        System.out.println(adaptiveExtension.getClass());
    }

    /**
     getActivateExtension
     1、首先看分组,如果值@Activate只配置了分组,那么就只匹配分组值
     2、会匹配url中的参数,如果分组和value都配置了。首先匹配分组,然后在匹配url中的参数key
    */
    @Test
    public void test1() {
        URL url = URL.valueOf("test://localhost/test");
        url = url.addParameter("value1","gggg");
        //只看分组,不看url中的参数
        List rabbitmq = ExtensionLoader.getExtensionLoader(ActivateApi.class).getActivateExtension(url, new String[]{"spring"}, "rabbitmq");
        System.out.println(rabbitmq.size());
        for (ActivateApi activateApi : rabbitmq) {
            System.out.println(activateApi.getClass());
        }
    }

    @Test
    public void defaultL() {
        //寻找@SPI注解中配置的value值
        System.out.println(ExtensionLoader.getExtensionLoader(ActivateApi.class).getDefaultExtension());
        System.out.println(ExtensionLoader.getExtensionLoader(ActivateApi.class).getDefaultExtensionName());

        //根据指定的name拿值
        System.out.println(ExtensionLoader.getExtensionLoader(ActivateApi.class).getExtension("mybatis"));
        System.out.println(ExtensionLoader.getExtensionLoader(ActivateApi.class).getSupportedExtensions());
    }

    @Test
    public void protocol() {
//        Protocol protocolproxy = ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension();
//        System.out.println(protocolproxy);
        System.out.println(ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension());
    }

    @Test
    public void proxyFactory() {
        System.out.println(ExtensionLoader.getExtensionLoader(ProxyFactory.class).getAdaptiveExtension());
    }

    @Test
    public void override() {
        RegistryFactory registryFactory = ExtensionLoader.getExtensionLoader(RegistryFactory.class).getAdaptiveExtension();
        Registry registry = registryFactory.getRegistry(URL.valueOf("zookeeper://192.168.67.19:2184"));
        registry.register(URL.valueOf("override://0.0.0.0/com.xiangxue.jack.service.UserService?category=configurators&dynamic=false&application=dubbo_provider&timeout=8900"));
    }

    @Test
    public void decode() {
        System.out.println(URL.decode("route%3A%2F%2F0.0.0.0%2Fcom.xiangxue.jack.service.UserService%3Fcategory%3Drouters%26dynamic%3Dfalse%26enabled%3Dtrue%26force%3Dfalse%26name%3DrouteTest%26priority%3D0%26router%3Dcondition%26rule%3Dmethod%2B%253D%2BqueryUser%2B%253D%253E%2Bprovider.cluster%2B%253D%2Bfailover%2B%2526%2Bprovider.host%2B%253D%2B192.168.90.126%2B%2526%2Bprovider.protocol%2B%253D%2Bdubbo%26runtime%3Dfalse"));
    }

    @Test
    public void providerReg() {
        RegistryFactory registryFactory = ExtensionLoader.getExtensionLoader(RegistryFactory.class).getAdaptiveExtension();
        Registry registry = registryFactory.getRegistry(URL.valueOf("zookeeper://192.168.67.19:2184"));
        registry.register(URL.valueOf("dubbo://192.168.2.23:20880/com.xiangxue.jack.service.UserService?anyhost=true&application=dubbo_provider&bean.name=ServiceBean:com.xiangxue.jack.service.UserService&connections=10&doKill.actives=10&doKill.executes=10&doKill.return=true&dubbo=2.0.2&generic=false&interface=com.xiangxue.jack.service.UserService&methods=doKill,queryUser&owner=world&pid=5704&revision=0.0.1-SNAPSHOT&side=provider×tamp=1626242405336&token=3d9492a1-c9ca-4bb4-a5de-a76a7a93684e"));
    }

}

到此两者区别分享完毕,大家稍后一定多多测试,定会很快掌握。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/868377.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-13
下一篇 2022-05-13

发表评论

登录后才能评论

评论列表(0条)

保存