TheRouter 的跨模块依赖注入实现原理
2023-02-18 15:50:10 时间
本文作者——张涛(货拉拉)
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 "返回用户信息";
}
};
}
相关文章
- 在线地图持续进化,BAT技术“鲜”发制人
- 阴阳五行在数据分析中的致命问题2011.11.5
- 知乎15篇书籍推荐帖子中的书名号统计2022.11.7
- 万维钢精英日课4统计学新书《让世界讲得通》2022.11.11
- 双十一天猫分类销售额简单看看2022.11.14
- 《数据与城市》走在理想的边缘2022.11.14
- #每周一本书计划#11月第3周《清单革命》
- @@知乎提问数据分析推荐书籍的统计分析2022.11.21
- 今年冬天是暖冬还是寒冬?拉尼娜2022.11.22
- 继续看今年的天气2022.11.22
- 领略设计模式的魅力,谈谈组合模式搭配访问者模式
- 玩转JVM中的对象及引用:从创建到引用到分配和优化策略
- k50的67w超快充只是前5分钟2022.11.26
- 二手图书多抓鱼的价格和推荐2022.11.29
- 拒绝躺平,如何使用AOP的环绕通知实现分布式锁
- 初探持续监测技术
- 本次降温有多冷2022.12.2
- #每周一本书#《事实》
- 好强的chatGPT,“我失业了”2022.12.8
- 中国香港第五波疫情数据分析2022.12.9