ServiceLoader
使用步骤
初始化ServiceLoader
1ServiceLoader.lazyInit();定义接口以及实现类,并添加@RouterService注解
1234public interface IEmvParamService {}true)(interfaces = IEmvParamService.class,key = ConfigServiceConstant.CONFIGSERVICE_EMVPARAM,singleton =public class EmvParamService implements IEmvParamService {}使用对应服务
1IEmvParamService service = Router.getService(IEmvParamService.class, ConfigServiceConstant.CONFIGSERVICE_EMVPARAM);
原理分析
1.编译期间,找到所有使用了@RouterService注解的类,使用APT技术生成初始化代码。
2.应用初始化调用ServiceLoader.lazyInit()时,使用反射调用com.sankuai.waimai.router.generated.service包下的类的init方法。
3.ServiceLoader.put方法逻辑,ServiceLoader内部维护了2级HashMap,通过2级HashMap实现了如下绑定关系
1.第一级HashMap绑定接口与ServiceLoader实例
loader = new ServiceLoader(IEmvParamService.class);
map1(IEmvParamService.class,loader)
2.第二级HashMap则是由接口对应的loader实例去调用,完成key与ServiceImpl的绑定
loader.putImpl(key, implementClass, singleton)
map2(“configService_emvparam”,new ServiceImpl(“configService_emvparam”, EmvParamService.class, true))
4.使用Router.getService(IEmvParamService.class, ConfigServiceConstant.CONFIGSERVICE_EMVPARAM);时先通过一级HashMap获取接口对应的ServiceLoader实例,再通过二级HashMap获取接口的实现类,然后通过ServiceLoader创建实现类的实例(使用反射创建,如果是单例,还会缓存到对象池中)
5.List