ServiceLoader
- ServiceLoder的SPI
- ServiceLoader.load(Driver.class)的作用
- 代码详解
- 出现的问题
- 解决方式
ServiceLoder的SPI
ServiceLoader.load(Driver.class)的作用
java.util.ServiceLoader工具类方法会使用ClassLoad类的getResources方法获取指定目录下的文件,读取文件内容并解析获取所有接口实现类的全限路径,根据全限路径使用class.forName装载class文件到JVM,然后通过c.newInstance()实例化类转化接口类型并放入providers缓存提供者集合中,以供后面使用。
代码详解
这里是想加载接口Driver 的实体类,那么实体类有哪些呢
public interface Driver extends AutoCloseable {
static Optional<Driver> get(DriverConfig config) {
Asserts.checkNotNull(config, "数据源配置不能为空");
ServiceLoader<Driver> drivers = ServiceLoader.load(Driver.class);
for (Driver driver : drivers) {
if (driver.canHandle(config.getType())) {
return Optional.of(driver.setDriverConfig(config));
}
}
return Optional.empty();
}
}
①MySqlDriver extends AbstractJdbcDriver
②AbstractJdbcDriver extends AbstractDriver
③AbstractDriver implements Driver
所以是MySqlDriver继承Driver
出现的问题
明明是MySqlDriver继承了Driver,
但是在进行:ServiceLoader drivers =ServiceLoader.load(Driver.class);的时候没有任何内容
我们这个接口所在的子项目是dlink-admin
实际上就是在dlink-admin里面无法读取到com.dlink.metadata.driver.MySqlDriver这个类,所以到接口Driver的时候,没有落到实体类上
解决方式
在dlink-admin这个项目里面引入dlink-metadata-mysql
在pom.xml文件里面,
加上:
<dependency>
<groupId>com.dlink</groupId>
<artifactId>dlink-metadata-mysql</artifactId>
</dependency>