Java 作为一种静态类型语言,以灵活性为代价换来了更多的编译期检查,使得代码在运行时出错的概率相对更低。然而,这也为代码编写者,尤其是 SDK 类项目的实现者带来了一些困难。本文论述了一种以较低成本解决API动态性不足的问题,同时又不丧失编译检查能力(对于 SDK 的使用者来说)的方案,希望给有类似需求的开发者一定的启示,旨在抛砖引玉。
问题描述
假设我们正在编写一个工具包,暴露了一个接口实例给用户。但是该工具包又希望通过插件的方式拓展它的 API,例如增加一个方法。但由于 Java 为静态语言,那么如何让一个静态语言实现动态的方法扩展呢?
现存方案
现有方案多少都有一些不完美的地方,虽然都能实现类似的效果。
注册、获取机制
这种方法实现起来非常简单,只需要提供一个单例作为插件注册中心。任何插件想要注入的方法可以通过这个注册中心注入,而调用者则通过插件名称获取相应插件提供的API:
public class APIUser {
APIRegistry reg = APIRegistry.INSTANCE;
public void registerAPI() {
reg.registerAPI("myAPI", new MyAPIImpl());
}
public void useMyAPI() {
MyAPI api = (MyAPI) reg.getAPI("myAPI");
api.extendedMethod();
}
}
这种方法的好处是极度灵活,还可以在运行时进行加载和卸载操作(生命周期管理);而坏处是需要使用者与插件提供者达成两处默契:使用正确的注册名以及使用正确的类型转换。
正因为它的灵活性,多数系统中采用的插件管理系统是基于这种形式的,例如 OSGI 框架中的服务注册机制。

本文探讨了Java静态类型语言在动态扩展API时的挑战,并提出了一种基于动态代码生成的新机制,允许在不牺牲编译检查能力的情况下低成本扩展SDK的API。通过用户自定义接口和SDK动态生成代理类,实现插件与SDK接口的无缝集成,降低用户与插件开发者之间的默契成本。
最低0.47元/天 解锁文章
1124

被折叠的 条评论
为什么被折叠?



