服务粉丝

我们一直在努力
当前位置:首页 > 财经 >

TheRouter 的跨模块依赖注入实现原理

日期: 来源:群英传收集编辑:徐宜生

点击上方蓝字关注我,知识会给你力量


本文作者——张涛(货拉拉)

TheRouter用于跨模块通信设计的ServiceProvider,核心设计思想是参考了SOA(面向服务架构)的设计方式。

具体到 Android 侧就是 AIDL 类似的实现。

模块化能力支持项:

  • 支持跨模块依赖注入
  • 支持自定义注入项的创建规则,依赖注入可自定义参数
  • 支持自定义服务拦截,单模块mock调试
  • 支持注入对象缓存,多次注入 只会new一次对象

1.0 依赖注入

用于跨模块通信使用,核心设计思想是参考了SOA(面向服务架构) 的设计方式。具体到 Android 侧就是 AIDL 类似的实现:
例如当前有两个模块:A订单模块、B登录模块,下单需要获取用户信息。
这个业务场景就是,A需要使用获取用户信息的服务,B需要向外提供一个获取用户信息的服务。

1.1 声明接口服务

首先声明一个接口,放入公共依赖层

// 假设当前有一个用户信息获取服务
public interface IUserService {
    String getUserInfo();
}

1.2 服务使用方

也就是上面例子的 A订单模块,他需要使用获取用户信息的服务 A无需关心,IUserService这个接口服务是谁提供的,他只需要知道自己需要使用这样的一个服务就行了。
「注」:如果没有提供服务的提供方,TheRouter.get()可能返回null

TheRouter.get(IUserService::class.java)?.getUserInfo()

1.3 服务提供方

服务提供方需要声明一个提供服务的方法,用@ServiceProvider注解标记。

  • 如果是 java,必须是 public static 修饰
  • 如果是 kotlin,建议写成 top level 的函数
  • 方法名不限
/**
 * 方法名不限定,任意名字都行
 * 返回值必须是服务接口名,如果是实现了服务的子类,需要加上returnType限定(例如下面代码)
 * 方法必须加上 public static 修饰,否则编译期就会报错
 */
@ServiceProvider
public static IUserService test() {
    return new IUserService() {
        @Override
        public String getUserInfo() {
            return "返回用户信息";
        }
    };
}

// 也可以直接返回对象,然后标注这个方法的服名是什么
@ServiceProvider(returnType = IUserService.class)
public static UserServiceImpl test() {
    xxx
}

2.0 自定义服务拦截器

「使用场景」:单模块调试时,可能会有需要 mock 其他模块提供的服务,TheRouter 允许自定义其他模块的实现。

Interceptor interceptor = new Interceptor() {
    @Override
    public <T> T interception(Class<T> clazz, Object... params) {
        if (clazz == IUserService.class) {
            return new IUserService();
        }
        return null;
    }
};
TheRouter.getRouterInject().addInterceptor(interceptor);

3.0 服务缓存

服务提供方运行对提供的服务做配置,对于无状态的服务,尽可能使用缓存方式减少对象创建次数,而有状态的服务,则每次创建新对象保证多次调用有不会互相污染状态(例如订单状态管理、商品销售状态等服务)。

声明服务缓存只需要在 @ServiceProvider的方法上新增额外注解即可,例如下面示例代码:

  • 「Singleton」 表示这个对象会被永久缓存,对外部调用方而言相当于这个对象声明成了单例
  • 「NewInstance」 表示每次都会返回新对象

「注」:如果两个注解同时被添加,则只有Singleton会生效。


// 注:如果都不加,默认是LRU+软引用缓存
// 如果两个注解同时被添加,则只有Singleton会生效。
@Singleton // 对外部调用方而言相当于这个对象声明成了单例
@NewInstance  // 每次都会返回新对象
public interface IUserService {
    public String getUserInfo();
}


@ServiceProvider
public static IUserService test() {
    return new IUserService() {
        @Override
        public String getUserInfo() {
            return "返回用户信息";
        }
    };
}

向大家推荐下我的网站 https://xuyisheng.top/  点击原文一键直达

专注 Android-Kotlin-Flutter 欢迎大家访问



往期推荐


本文原创公众号:群英传,授权转载请联系微信(Tomcat_xu),授权后,请在原创发表24小时后转载。
< END >
作者:徐宜生

更文不易,点个“三连”支持一下

相关阅读

  • kotlin修炼指南8—集合中的高阶函数

  • 点击上方蓝字关注我,知识会给你力量Kotlin对集合操作类新增了很多快捷的高阶函数操作,各种操作符让很多开发者傻傻分不清,特别是看一些Kotlin的源码或者是协程的源码,各种眼花缭
  • kotlin修炼指南9-Sequence的秘密

  • 点击上方蓝字关注我,知识会给你力量人们经常忽略Iterable和Sequence之间的区别。这是可以理解的,因为即使它们的定义也几乎是相同的。interface Iterable<out T> { operato
  • Flutter混编工程之异常处理

  • 点击上方蓝字关注我,知识会给你力量Flutter App层和Framework层的异常,通常是不会引起Crash的,但是Engine层的异常会造成Crash。而Flutter Engine部分的异常,主要是libfutter.so
  • 闲言碎语-第八期

  • 点击上方蓝字关注我,知识会给你力量时间一晃就过去了,22年的总结还没来得及写,转眼已经2023年了。22年对于很多人来说,应该都是比较魔幻的一年,特别是在上海的朋友,一小半的时间都
  • 来自亲爹的爱,有但是不多~!

  • 有了宝宝后麻麻们总觉得爸爸跟不上育儿步伐都说爸爸带娃只有三分钟热度麻麻们纷纷表示“带的很好,下次别带了”其实,新一代爸比育儿有方法快来看看他们都是怎么应对—····
  • 所有美好都在冬日沉淀

  • 冬日·美好HELLO WINTER致可爱的你寒冷的冬日来袭,气温骤降外面开始感到阵阵寒意但是我们依然可以通过细微之处将冬日的生活过得热气腾腾幸福满满守护陪伴冬日HELLO SNOW时节

热门文章

  • “复活”半年后 京东拍拍二手杀入公益事业

  • 京东拍拍二手“复活”半年后,杀入公益事业,试图让企业捐的赠品、家庭闲置品变成实实在在的“爱心”。 把“闲置品”变爱心 6月12日,“益心一益·守护梦想每一步”2018年四

最新文章

  • TheRouter 的跨模块依赖注入实现原理

  • 点击上方蓝字关注我,知识会给你力量本文作者——张涛(货拉拉)TheRouter用于跨模块通信设计的ServiceProvider,核心设计思想是参考了SOA(面向服务架构)的设计方式。具体到 Androi
  • kotlin修炼指南8—集合中的高阶函数

  • 点击上方蓝字关注我,知识会给你力量Kotlin对集合操作类新增了很多快捷的高阶函数操作,各种操作符让很多开发者傻傻分不清,特别是看一些Kotlin的源码或者是协程的源码,各种眼花缭
  • kotlin修炼指南9-Sequence的秘密

  • 点击上方蓝字关注我,知识会给你力量人们经常忽略Iterable和Sequence之间的区别。这是可以理解的,因为即使它们的定义也几乎是相同的。interface Iterable<out T> { operato
  • 后新冠时代

  • 自从国家卫健委宣布防控放开之后,所有人都为之一震,原来的【躺平党】慌了,就这么分开了,都不缓一缓吗?原来的【封控党】也慌了,就这么分开了,我们的脸往哪放啊?也许刚放开的时候,大家
  • Flutter混编工程之异常处理

  • 点击上方蓝字关注我,知识会给你力量Flutter App层和Framework层的异常,通常是不会引起Crash的,但是Engine层的异常会造成Crash。而Flutter Engine部分的异常,主要是libfutter.so