cola4.0 扩展点使用及源码浅析

最近新项目里面用了cola框架,里面有一个扩展点,特定去撸了一下它的源码,把它整明白了

Cola扩展点使用

Cola中提供了一种扩展点的机制,允许我们通过bizId(组织ID)、useCase(使用案例)、scenario(业务场景)三者动态的去选择实现类。有点类似与我们的策略模式,在程序运行的过程中,动态的选择实现类去处理我们的请求。

我就不多做解释了,下面的例子看了,就能明白这个扩展点怎么用了。

1、定义扩展点接口,实现ExtensionPointI

public interface OrganizationExtPt extends ExtensionPointI {
    /**
     * 根据corpId查询企业下所有部门
     *
     * @return 部门
     */
    String getDepartmentsByCorpId();
}

2、钉钉场景扩展点实现

@Extension(bizId = "organize",useCase = "getByCorpId",scenario = "dingTalk")
public class DingTalkOrganizationExt implements OrganizationExtPt {

    @Override
    public String getDepartmentsByCorpId() {
        System.out.println("在组织结构业务,通过企业编号获取部门列表的用例,在钉钉的场景下业务的实现处理方式");
        System.out.println("通过钉钉的配置信息和API获取得到组织信息,并组装成云枢识别的部门信息");

        return "钉钉";
    }
}

3、微信扩展点接口实现

@Extension(bizId = "organize",useCase = "getByCorpId",scenario = "wechat")
@Slf4j
public class WechatOrganizationExt implements OrganizationExtPt{
    public String getDepartmentsByCorpId() {
        log.info("业务:组织机构,用例:通过企业编号获取部门 , 场景:企业微信");
        log.info("通过企业微信的API获取组织的部门信息,然后包装为需要的部门列表");

        return "微信";
    }
}

4、扩展点使用
在命令执行器中使用。

@Component
public class OrgazationQueryExe {
    @Resource
    private ExtensionExecutor extensionExecutor;

    public String execute(OrgnizationQry cmd) {
        return extensionExecutor.execute(OrganizationExtPt.class, cmd.getBizScenario(),
                ex -> ex.getDepartmentsByCorpId());
    }
}

5、测试扩展点的使用

@RestController
public class OrganizationController {

    @Resource
    private OrgazationQueryExe orgazationQueryExe;

    @GetMapping(value = "/organization/getDepartmentsByCorpId/{corpId}/{scenario}")
    public String listCustomerByName(@PathVariable("corpId") String corpId, @PathVariable("scenario") String scenario){

        OrgnizationQry qry = new OrgnizationQry();
        qry.setCorpId(corpId);
        qry.setIncludeDelete(true);
        qry.setBizScenario(BizScenario.valueOf("organize","getByCorpId",scenario));

        return orgazationQueryExe.execute(qry);
    }
}

在这里插入图片描述
可以看到,根据我们参数的不同,最终处理的实现类也不同。

扩展点原理探究

第一次使用Cola扩展点后,我就在想,它是怎么找到具体的实现的?而在我们上面的代码实例中,唯一的入口就是下面这段代码:

 extensionExecutor.execute(OrganizationExtPt.class, cmd.getBizScenario(),
                ex -> ex.getDepartmentsByCorpId());

因此,跟进去看看源代码是怎么实现的。

public <R, T> R execute(Class<T> targetClz, BizScenario bizScenario, Function<T, R> exeFunction) {
        // 1.找到负责执行的具体实现类
        T component = locateComponent(targetClz, bizScenario);
        // 2.执行
        return exeFunction.apply(component);
    }

继续往下跟的话,发现实现类是从extensionRepository 中获取的。所以,升起了第二个疑问:实现类是什么时候被放到extensionRepository中去的?

这时候,利用IDEA定位到cola有关扩展点源码的位置:
cola4.0 扩展点使用及源码浅析_第1张图片
根据SpringBoot自动配置的机制,我们知道ExtensionAutoConfiguration 会被Spring初始化,因此这是我们进一步探究源码的入口。

@Configuration
public class ExtensionAutoConfiguration {

    @Bean(initMethod = "init")
    @ConditionalOnMissingBean(ExtensionBootstrap.class)
    public ExtensionBootstrap bootstrap() {
        return new ExtensionBootstrap();
    }

    @Bean
    @ConditionalOnMissingBean(ExtensionRepository.class)
    public ExtensionRepository repository() {
        return new ExtensionRepository();
    }

    @Bean
    @ConditionalOnMissingBean(ExtensionExecutor.class)
    public ExtensionExecutor executor() {
        return new ExtensionExecutor();
    }

    @Bean
    @ConditionalOnMissingBean(ExtensionRegister.class)
    public ExtensionRegister register() {
        return new ExtensionRegister();
    }
}

我看名字猜了一下,ExtensionBootstrap很明显与初始化相关,因此就去看一下它到底做了什么。然后大概画了一个流程图。具体的代码我就不带大家一起看了(因为我觉得自己去看代码会更清楚,这代码挺容易看懂的)
cola4.0 扩展点使用及源码浅析_第2张图片
简单来说就是:

  1. 在初始化的时候,它会去找Spring容器中带有@Extension注解的Bean
  2. 将这些Bean注册到ExtensionRepository中
    a. ExtensionRepository可以简单理解成一个Map
    i. Key:ExtensionCoordinate,由接口名称、bizId、useCase、scenario组成
    ii. value:对应的具体实现类
  3. 现在我们就可以理解extensionExecutor.execute中的俩个参数了。根据这俩个参数就可以组装成一个ExtensionCoordinate
    a. Class targetClz:目标接口
    b. BizScenario:包含bizId、useCase、scenario

参考文章:
https://www.cnblogs.com/snidget/p/12961700.html

你可能感兴趣的:(java基础,java)