一些优秀的开源框架,比如Dubbo、Hystrix等,总会给开发者留一个后门,方便对其中的某一块功能,根据公司自身生态进行有效的扩展,比如Neflix开源的Hystrix,其实Hystrix的代码写的真的很好,除了RxJava那部分晦涩的实现。
在Hystrix中的插件实现中,提供了5个扩展点,通过实现这些插件接口,可以很好的结合公司内部框架进行使用,比如数据埋点、动态配置等等,下面以事件通知接口为例子,看看Hystrix是如何实现的。
通过 getEventNotifier方法获取事件通知器,当然了,一开始是没有初始化的,先尝试使用 getPluginImplementation方法,看看能不能拿到,拿不到就使用本地默认的实现。
这里,Hystrix还提供了另外一种实现,很简单,就不解释了,这里的重点是 findService实现。
其实,这里的实现是使用Java内置的SPI机制,SPI是什么?
SPI 全称为 Service Provider Interface),是一种服务提供发现机制,通过 ServiceLoader类的load方法,可以自动找到实现对应接口的实现类,为了更清晰的了解其中原理,可以去看看load方法的源码实现。
一个大概的过程是:load方法会尝试在classpath下META-INF/services/文件夹下查找一个文件,其中文件名是接口的全限定名。
如上图所述,为了给CacheKeyFilter接口提供可扩展性,内部使用ServiceLoad加载实现类对象,在业务的项目中,重新实现该接口,在文件夹META-INF/services/下面创建对应的文件,并在文件中指定该接口实现类的全限定名。
当然了,你也可以指定多个,但是没啥意义,找到这些实现类之后,ServiceLoad内部会通过反射机制,即通过class.newInstance()方式进行实例化,不过,这种就要求实现类必须有无参构造函数了。
通过这种方式,我们就可以愉快的对开源框架所提供的接口进行扩展,加入各种骚操作,还不动手试试?