您现在的位置是:首页 > 文章详情

Java SPI机制

日期:2018-10-14点击:517

0

很久没有写博客了,这一两个月基本上就是找工作——离职——入职。到今天基本上入职近一个月了,在看公司代码的时候发现使用到了SPI技术来进行解耦,这篇文章主要写下SPI的基本使用。

1. SPI基本概念

SPI的全名叫Service Provider Interface,其主要是针对厂商或者插件的。我的理解就是上层提供接口,我们需要去实现,并且上层只需要根据我们的配置文件即可拿到我们的实现类(反射获取)。

2. SPI代码

先看下目录结构:


img_e431120865c7aa65f2eac7d8c66a1a11.png
目录结构

2.1 接口定义

定义一个接口IStudy

public interface IStudy { void study(); } 

2.2 编写实现类

编写两个实现类NormalStudySuperStudy

public class NormalStudy implements IStudy { @Override public void study() { System.out.println("normal study"); } } public class SuperStudy implements IStudy { @Override public void study() { System.out.println("super study"); } } 

2.3 创建com.nick.test.IStudy文件

在src目录下创建META-INF\services\com.nick.test.IStudy文件,并在文件中添加两个实现类:

com.nick.test.NormalStudy com.nick.test.SuperStudy 

2.4 测试

public class Test { public static void main(String[] args) { ServiceLoader<IStudy> searches = ServiceLoader.load(IStudy.class); Iterator<IStudy> iterator = searches.iterator(); while (iterator.hasNext()) { iterator.next().study(); } } } 

2.5 输出

img_dac6184224e5e9fd3be5a78c07c816a7.png
结果

3 原理简单分析

大致原理其实通过上面的示例应该都知道了:通过读取META-INF/services/com.nick.test.IStudy文件的内容来确定接口对应的实现类,最终通过反射来进行实现类的加载。

核心代码:

try { Enumeration<URL> resource = Test.class.getClassLoader().getResources("META-INF/services/" + IStudy.class.getName()); while (resource.hasMoreElements()) { URL url = resource.nextElement(); InputStream inputStream = url.openStream(); BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "utf-8")); String s; while ((s = bufferedReader.readLine()) != null) { System.out.println(s); } } } catch (IOException e) { e.printStackTrace(); } 

输出:

com.nick.test.NormalStudy com.nick.test.SuperStudy 

最后通过反射加载并创建对象即可,原理还是很简单的!

原文链接:https://yq.aliyun.com/articles/665819
关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

文章评论

共有0条评论来说两句吧...

文章二维码

扫描即可查看该文章

点击排行

推荐阅读

最新文章