乐趣区

关于android: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 "返回用户信息";}
    };
}
退出移动版