我是靠谱客的博主 健康毛豆,最近开发中收集的这篇文章主要介绍如何跨项目使用SPI扩展点,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

    SPI-服务扩展点可以使得项目结构更加解耦,比如我司在支付方式模块中,全平台都可以使用在线支付,单由于业务场景要求,不同的业务实例会有定制化的支付方式,如非国有性质的采购人可以申请使用账期支付等。原先的技术实现是有订单模块代码中根据业务实例写死一堆的if-else业务实现,随着接入业务的增加,代码变得越来越臃肿和不可维护。为了该模块更具扩展性和易维护性,我们希望通过由订单中心提供支付方式SPI扩展接口,不同的业务线可以更灵活的配置各自的支付方式。

    在一个项目中定义一个扩展接口,然后写不同的实现,并在项目中的META-INF/services路径下写好扩展点实现路径,然后项目在启动的时候回加载这些实现;现在的问题是如何在不同的项目中使用SPI,也就是项目A定义了一个SPI接口,项目B和项目C在实现了其接口后,项目A怎么找到这些实现?这里大概有两种方式:

  • 通过JAR包,项目B和项目C实现项目A的SPI接口后,打包成JAR后放到项目A中;
  • 通过dubbo注册中心机制,项目B和项目C在实现项目A的SPI接口后,向注册中心注册其实现,然后项目A再通过注册中心获取具体实现类和方法;

    由于小菜不想每次修改实现或有新接入方时都要重新打包,并复制给SPI提供方,来来回回,不仅繁琐,而且中间也容易出错。所以这里主要探讨第二种方案是怎么做的。

注解和反射技术是做这件事的一大利器。

1、首先,应该定义一个注解,用于标识那些接口是SPI接口;凡是接口有该注解的,我们单独先把它拎出来;

import java.lang.annotation.*;

/**
 * 标记一个 dubbo 接口是否为 SPI 接口
 */
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
public @interface SPIInterface {
    /**
     * SPI所属应用
     *
     * @return
     */
    String appName();

    /**
     * SPI所属的功能
     *
     * @return
     */
    String function();

    /**
     * SPI描述
     *
     * @return
     */
    String desc();
}

2、识别了那些事SPI接口,我们自然会想到该如何识别那些类是SPI接口的实现类;同理:

import org.springframework.stereotype.Component;
import java.lang.annotation.*;

/**
 * 标记一个实现类为SPI的扩展实现
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
public @interface SPIProvider {
    /**
     * SPI实现类的描述
     *
     * @return
     */
    String desc();

    /**
     * SPI服务提供方式:jar or rpc
     *
     * @return
     */
    SPIProviderMode providerMode() default SPIProviderMode.JAR;

    /**
     * SPI分组标签
     *
     * @return
     */
    String label();

    /**
     * 是否为默认的SPI实现
     *
     * @return
     */
    boolean defaultProvider() default false;
}

凡是实现类有该注解的,我们会把它看做是某一SPI接口的实现类;

3、假设项目B和项目C实现项目A的SPI接口,实现完之后,我们希望该实现类能够已dubbo服务的形式上传到注册中心;

4、项目A通过注册中心找到对应的服务类,具体由SPIProvider的label标签区分不同的业务线实现;

最后

以上就是健康毛豆为你收集整理的如何跨项目使用SPI扩展点的全部内容,希望文章能够帮你解决如何跨项目使用SPI扩展点所遇到的程序开发问题。

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

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

评论列表共有 0 条评论

立即
投稿
返回
顶部