首页 > 其他分享 >各种spi机制实现与使用

各种spi机制实现与使用

时间:2024-08-15 22:15:33浏览次数:8  
标签:factoryType dubbo 实现 接口 spi apache 机制

SPI机制认识

1.java SPI机制

java SPI机制(service provider interface) jdk内置的服务提供发现机制,可以启用框架扩展或替换组件,主要思想是将装配的控制权移到程序之外

通俗的讲就是:为某个接口自动找到实现类并初始化。

使用:

  1. 定义接口
  2. 编写实现类实现接口逻辑
  3. 在类路径下添加目录META-INF/services,并在其下添加以接口权限定类名为名字的文件,内容是实现类的全限定类型名
  4. 使用ServiceLoader.load(接口)
    ServiceLoader contents = ServiceLoader.load(Content.class);
    Iterator iterator = contents.iterator();
    while (iterator.hasNext()) {
    // 调用next()时会使用Class.forName()加载类
    Content content = iterator.next();
    String searchContent = content.searchContent();
    System.out.println("searchContent = " + searchContent);
    }
    缺点:一次性加载所有的实现类,不能实现按需加载

2.spring的 SPI机制

spring会加载所有jar包下的META-INF/spring.factories文件下的所有自动配置类(xxAutoConfiguration),根据引入的starter,会对相应的类进行实例化,在实例化的过程中又会读取xxProperties类中的属性值,此属性值是在application.yml中进行配置的

使用

  1. 定义接口
  2. 编写实现类实现接口逻辑
  3. 在类路径下添加目录META-INF/spring.factories文件,文件内容key=val01,val02。key是接口权限定类名,val是实现类的全限定类型名
  4. 使用SpringFactoriesLoader.loadFactories(接口.class, 类加载器)
    ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
    List factories = SpringFactoriesLoader.loadFactories(Content.class, contextClassLoader);

源码

public static <T> List<T> loadFactories(Class<T> factoryType, @Nullable ClassLoader classLoader) {
    Assert.notNull(factoryType, "'factoryType' must not be null");
    ClassLoader classLoaderToUse = classLoader;
    if (classLoaderToUse == null) {
        classLoaderToUse = SpringFactoriesLoader.class.getClassLoader();
    }
    // 读取配置内容
    List<String> factoryImplementationNames = loadFactoryNames(factoryType, classLoaderToUse);
    if (logger.isTraceEnabled()) {
        logger.trace("Loaded [" + factoryType.getName() + "] names: " + factoryImplementationNames);
    }
    List<T> result = new ArrayList<>(factoryImplementationNames.size());
    for (String factoryImplementationName : factoryImplementationNames) {
        // Class.forName()实例化
        result.add(instantiateFactory(factoryImplementationName, factoryType, classLoaderToUse));
    }
    AnnotationAwareOrderComparator.sort(result);
    return result;
}

参考:深入剖析Spring Boot 的SPI机制

3.dubbo的spi机制

以apache不是alibaba的dubbo实现。使用过滤器为案例

  • 使用一个类实现org.apache.dubbo.rpc.Filter中invoke方法,类上并标注@Activate注解
    @Activate注解有group属性,order属性。
    group属性表示当前spi扩展在什么时候起作用。CommonConstants.PROVIDER表示:作为服务器(生产者)、CommonConstants.CONSUMER表示客户端(消费者)
    order表示被执行的顺序,数字越小优先级越高
    代码如下
    import org.apache.dubbo.common.constants.CommonConstants;
    import org.apache.dubbo.common.extension.Activate;
    import org.apache.dubbo.rpc.*;

    @Activate(group = {CommonConstants.PROVIDER, CommonConstants.CONSUMER})
    public class LogRecordSPI implements Filter {
    
        @Override
        public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
            try {
                return invoker.invoke(invocation);
            } catch (RpcException e) {
                System.out.println("RpcException");
                throw new RuntimeException(e);
            } finally {
                System.out.println("finally");
            }
        }
    }
    
  • 项目resources目录中创建目录META-INF/dubbo,并创建一个以org.apache.dubbo.rpc.Filter,内容是spi服务id=xxx.xx.xxx.LogRecordSPI,如下
    logRecordSP=com.abucloud.spi.LogRecordSPI
    参考:调用拦截扩展

标签:factoryType,dubbo,实现,接口,spi,apache,机制
From: https://www.cnblogs.com/party-abu/p/18361905

相关文章

  • Spring Boot集成Spring Cloud Stream实现消息驱动微服务
    SpringBoot集成SpringCloudStream实现消息驱动微服务大家好,我是微赚淘客返利系统3.0的小编,是个冬天不穿秋裤,天冷也要风度的程序猿!在构建微服务架构时,消息驱动的微服务是一种常见的设计模式。SpringCloudStream提供了一种简单而强大的模型来发送和接收消息,从而实现解耦和异......
  • C语言-使用数组法,指针法实现将一个5X5的矩阵中最大的元素放在中心,四个角分别放四个最
    1.题目要求:将一个5X5的矩阵中最大的元素放在中心·,四个角分别放四个最小的元素(顺序为从左到右,从上到下,从小到大存放),写一函数实现之。2.数组法实现#define_CRT_SECURE_NO_WARNINGS1#include<stdio.h>//一、数组法实现intmain(){ intarr[5][5]={ {1,2,3,4,5},......
  • Spring Boot集成Hystrix实现服务容错
    SpringBoot集成Hystrix实现服务容错大家好,我是微赚淘客返利系统3.0的小编,是个冬天不穿秋裤,天冷也要风度的程序猿!在微服务架构中,服务之间的依赖关系错综复杂,任何一个服务的故障都可能影响到整个系统的稳定性。为了提高系统的容错性,引入断路器模式是一种有效的解决方案。Hystrix......
  • 使用 Flask、Celery 和 Python 实现每月定时任务
    为了创建一个使用Flask、Celery和Python实现的每月定时任务,我们需要按照以下步骤进行:1.安装必要的库我们需要安装Flask、Celery和Redis(作为消息代理)。我们可以使用pip来安装它们:bash复制代码​pipinstallflaskceleryredis2.设置Flask和Celery首先,我们需......
  • ArcGIS Pro 实现人口分布栅格TIFF数据的网格提取与可视化
    这里在分享一个人口1km精度栅格数据,LandScan是由美国能源部橡树岭国家实验室(ORNL)提供的全球人口分布数据集,具有最高分辨率的全球人口分布数据,是全球人口数据发布的社会标准,是全球最为准确、可靠,基于地理位置的,具有分布模型和最佳分辨率的全球人口动态统计分析数据库。这一数据......
  • 云计算实训30——mysql主从复制同步、mysql5.7版本安装配置、python操作mysql数据库、
    一、mysql主从复制及同步1、mysql主从自动开机同步2、配置mysql5.7版本mysql-5.7.44-linux-glibc2.12-x86_64.tar启动服务、登录对数据库进行基本操作3、使用python操纵mysql数据库4、编辑python脚本自动化操纵mysql数据库二、mycat读写分离......
  • Python实现最长回文字符串
    题目最长回文字符串是一种对称的字符串,如s="ababd",其中"aba"或"bab"都是回文字符串。求解思路最开始的思路是用类似括号匹配的放手,利用栈来做“对对消”,来判断一个字符串是不是回文字符串,但实际操作中发现“对称轴”元素是不确定的,前面的消除会导致后面的无法对比。然后......
  • FPGA实现HDMI传输(一)
    1.HDMIHDMI全称(HighDefinitionMultimediaInterface)高清多媒体接口,支持在单线缆上传输全数字高清视频和多声道音频。HDMI标准的发展历史:日立、松下、飞利浦、SiliconImage、索尼、汤姆逊、东芝七家公司共同组建了HDMI高清多媒体接口组织,着手制定一种符合高清时代标准的全新......
  • 人工智能战略:如何实施人工智能解决方案以实现企业成功
    人工智能(AI)不再是一个未来概念,而是改变全球各行各业的切实现实。企业正在利用人工智能来提高效率、提高生产力并获得竞争优势。然而,实施人工智能解决方案需要明确的战略。本指南将引导您完成成功将人工智能融入业务运营的关键步骤,确保您充分利用其潜力,实现业务成功。......
  • MFC自定义按钮实现
    MFC中要实现自定义按钮,首先要创建一个类并继承自CButton。我这里创建的类名为CMainButtonclassCMainButton:publicCButton{ DECLARE_DYNAMIC(CMainButton)public: CMainButton(UINTnID,CRectrcWnd,CWnd*pParent=nullptr);//nID为按钮ID,rcWnd为按钮位置 virtual~CM......