2、SOFA RPC 源码解析 —— SPI篇

SOFA RPC 源码解析
1、SOFA RPC 源码解析 —— 服务发布篇
从SOFA RPC 源码解析 —— 服务发布篇中来看有很多地方我都提到了SPI,那么什么是SPI呢,我们简单介绍下JAVA的SPI流程:JAVA的SPI运行流程是运用java.util.ServiceLoader这个类的load方法去在src/META-INF/services/寻找对应的全路径接口名称的文件,然后在文件中找到对应的实现方法并注入实现,然后你可以使用了。(点击JAVA SPI),话不多说,我们有了大概的spi的概念后就来看下SOFA RPC是怎么实现SPI的。
我们就从熟悉的代码开始吧:

public class RpcServer {
   
   
    public static void main(String[] args) {
   
   
        // 构建RegistryConfig 注册配置
        RegistryConfig registryConfig = new RegistryConfig().setProtocol("zookeeper").setAddress("127.0.0.1:2181");
        RegistryConfig registryConfig1 = new RegistryConfig().setProtocol("zookeeper").setAddress("127.0.0.1:2181");
        List<RegistryConfig> registryConfigs = new ArrayList<RegistryConfig>();
        registryConfigs.add(registryConfig);
        registryConfigs.add(registryConfig1);
        // 构建ServerConfig 服务配置
        List<ServerConfig> serverConfigs = new ArrayList<ServerConfig>();
        ServerConfig serverConfig = new ServerConfig().setProtocol("bolt").setPort(12200).setDaemon(false);
        ServerConfig serverConfig1 = new ServerConfig().setProtocol("rest").setPort(12200).setDaemon(false);
        serverConfigs.add(serverConfig);
        serverConfigs.add(serverConfig1);
        // 构建发布配置
        ProviderConfig<HelloService> providerConfig = new ProviderConfig<HelloService>().setApplication(new ApplicationConfig().setAppName("paul")).setInterfaceId(HelloService.class.getName()).setRef(new HelloServiceImpl()).setServer(serverConfigs).setRegistry(registryConfig);
        // 正式发布
        providerConfig.export();
    }
}

上面那个代码就是我第一篇SOFA RPC 源码解析 —— 服务发布篇里面的,
我们再次简单分解下,就从第一步构建RegistryConfig 注册配置里面用到的SPI来讲:
点进去RegistryConfig的父类AbstractIdConfig

/**
 * 默认配置带ID
 *
 * @param <S> the sub class of AbstractIdConfig
 * @author <a href=mailto:zhanggeng.zg@antfin.com>GengZhang</a>
 */
public abstract class AbstractIdConfig<S extends AbstractIdConfig> implements Serializable {
   
   

    private static final long          serialVersionUID = -1932911135229369183L;

    /**
     * Id生成器
     */
    private final static AtomicInteger ID_GENERATOR     = new AtomicInteger(0);

    static {
   
   
        RpcRuntimeContext.now();
    }
    ...

再点进去静态模块里的RpcRuntimeContext,找到:

    static {
   
   
        if (LOGGER.isInfoEnabled()) {
   
   
            LOGGER.info("Welcome! Loading SOFA RPC Framework : {}, PID is:{}", Version.BUILD_VERSION, PID);
        }
        put(RpcConstants.CONFIG_KEY_RPC_VERSION, Version.RPC_VERSION);
        // 初始化一些上下文
        initContext();
        // 初始化其它模块
        ModuleFactory.installModules();
        // 增加jvm关闭事件
        if (RpcConfigs.getOrDefaultValue(RpcOptions.JVM_SHUTDOWN_HOOK, true)) {
   
   
            Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
   
   
                @Override
                public void run() {
   
   
                    if (LOGGER.isWarnEnabled()) {
   
   
                        LOGGER.warn("SOFA RPC Framework catch JVM shutdown event, Run shutdown hook now.");
                    }
                    destroy(false);
                }
            }, "SOFA-RPC-ShutdownHook"));
        }
    }

这里面的 ModuleFactory.installModules();就用到了SPI,根据配置加载扩展模块,一起来看看吧:

    /**
     * 加载全部模块
     */
    public static void installModules() {
   
   
        ExtensionLoader<Module> loader = ExtensionLoaderFactory.getExtensionLoader(Module.class);
        String moduleLoadList = RpcConfigs.getStringValue(RpcOptions.MODULE_LOAD_LIST);
        for (Map.Entry<String, ExtensionClass<Module>> o : loader.getAllExtensions().entrySet()) {
   
   
            String moduleName = o.getKey();
            Module module = o.getValue().getExtInstance();
            // judge need load from rpc option
            if (needLoad(moduleLoadList, moduleName)) {
   
   
                // judge need load from implement
                if (module.needLoad()) {
   
   
                    if (LOGGER.isInfoEnabled()) {
   
   
                        LOGGER.info("Install Module: {}", moduleName);
                    }
                    module.install();
                    INSTALLED_MODULES.put(mo
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值