java服务发现_java学习-原生服务发现-SPI

SPI : service provider interface, 其实际是java提供的一套用于被第三方实现或扩展的API

其体现了 java 基于接口编程的思想, 可以搭配策略模式以及配置文件实现自定义扩展

例如 :数据库驱动,日志,spring,以及dubbo/druid等

关于SPI 相关配置文件

根据 java.util.ServiceLoader 中的注释, 首先需要创建一个 待扩展类全名称的文件, 对于 待扩展类建议要求使用 interface / abstract class ,并不推荐使用 concrete class;

对于文件中的内容要求为当前服务提供者的子级(继承/实现),且要求必须存在一个公共的无参构造函数支持实例化

对于文件所处路径必须为 META-INF/services 路径中

具体使用

使用 java.util.ServiceLoader#load(java.lang.Class), 其还存在一个重载方法支持传递自定义classLoader

通过传递serviceProvider 类型来创建一个ServiceLoader对象, 通过获取其迭代器,遍历迭代器来实现扩展服务加载;

对于服务实现类的加载是在调用 迭代时生成的, 第一次加载时主要是利用到了反射, 当第一次加载完成后会存储到本地缓存中

代码示例

自定义接口作为 serviceProvider

/** Copyright (c) 2020, guoxing, Co,. Ltd. All Rights Reserved*/

packagecom.xingguo.spi;/*** Animal

*

*@authorguoxing

* @date 2020/12/20 12:17 PM

*@since

*/

public interfaceAnimal {voideat();

}

自定义相关实现类

/** Copyright (c) 2020, guoxing, Co,. Ltd. All Rights Reserved*/

packagecom.xingguo.spi;/*** Cat

*

*@authorguoxing

* @date 2020/12/20 12:18 PM

*@since

*/

public class Cat implementsAnimal {

@Overridepublic voideat() {

System.out.println("cat eat fish!!!");

}

}

/** Copyright (c) 2020, guoxing, Co,. Ltd. All Rights Reserved*/

packagecom.xingguo.spi;/*** Human

*

*@authorguoxing

* @date 2020/12/20 12:19 PM

*@since

*/

public class Human implementsAnimal {

@Overridepublic voideat() {

System.out.println("human eat anything what they can eat");

}

}

自定义spi文件(无后缀名)

文件路径 META-INF/services/com.xingguo.spi.Animal

文件中的内容, 使用"#"表示注释

#当前文件中也可以不存在任何内容

#要求当前concrete class 必须和当前文件名称所对应的类 存在层级关系,否则运行时会抛出错误

#且要求实现类中必须存在一个公共的无参构造函数

com.xingguo.spi.Cat

com.xingguo.spi.Human

测试类

/** Copyright (c) 2020, guoxing, Co,. Ltd. All Rights Reserved*/

packagecom.xingguo.spi;importjava.util.Iterator;importjava.util.ServiceLoader;/*** AnimalSPIDemo

* {@linkServiceLoader}

* {@linkAnimal src/META-INF/services/com.xingguo.spi.Animal}

*

*@authorguoxing

* @date 2020/12/20 12:20 PM

*@since

*/

public classAnimalSPIDemo {public static voidmain(String[] args) {

ServiceLoader animals = ServiceLoader.load(Animal.class, Thread.currentThread().getContextClassLoader());

Iterator iterator =animals.iterator();while(iterator.hasNext()) {

Animal next=iterator.next();

next.eat();

}

}

}

利用SPI实现 数据库 驱动加载

通过spi的方式来替代直接使用 Class.forName 加载的方式

要求工程引入相关数据库厂商的驱动jar包

spi文件定义

文件路径 META-INF/services/java.sql.Driver

文件中的内容

# mysql driver

com.mysql.cj.jdbc.Driver

相关测试类

/** Copyright (c) 2020, guoxing, Co,. Ltd. All Rights Reserved*/

packagecom.xingguo.spi.driver;importjava.sql.Driver;importjava.util.Iterator;importjava.util.ServiceLoader;/*** SqlDriverDemo

*

*@authorguoxing

* @date 2020/12/20 1:04 PM

*@since

*/

public classSqlDriverDemo {public static voidmain(String[] args) {

ServiceLoader load = ServiceLoader.load(Driver.class);

Iterator iterator =load.iterator();while(iterator.hasNext()) {

System.out.println(iterator.next()); // 输出的结果为 com.mysql.cj.jdbc.Driver@对象内存地址

}

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值