栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java SPI机制与在JDBC中的应用

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java SPI机制与在JDBC中的应用

什么是Java SPI?

    SPI的全名为:Service Provider Interface。在java.util.ServiceLoader的文档里有比较详细的介绍。简单的总结下 Java SPI 机制的思想。我们系统里抽象的各个模块,往往有很多不同的实现方案,比如日志模块的方案,xml解析模块、jdbc模块的方案等。面向的对象的设计里,我们一般推荐模块之间基于接口编程,模块之间不对实现类进行硬编码。一旦代码里涉及具体的实现类,就违反了可拔插的原则,如果需要替换一种实现,就需要修改代码。为了实现在模块装配的时候能不在程序里动态指明,这就需要一种服务发现机制。
    Java SPI 就是提供这样的一个机制:为某个接口寻找服务实现的机制。有点类似IOC的思想,就是将装配的控制权移到程序之外,在模块化设计中这个机制尤其重要Java SPI 的具体约定为:当服务的提供者,提供了服务接口的一种实现之后,在jar包的meta-INF/services/目录里同时创建一个以服务接口命名的文件。该文件里就是实现该服务接口的具体实现类。而当外部程序装配这个模块的时候,就能通过该jar包meta-INF/services/里的配置文件找到具体的实现类名,并装载实例化,完成模块的注入。基于这样一个约定就能很好的找到服务接口的实现类,而不需要再代码里制定。jdk提供服务实现查找的一个工具类:java.util.ServiceLoader。

Java SPI使用demo
  1. 定义一个接口:
package com.hiwei.spi.demo;
public interface Animal {
    void speak();
}
  1. 创建两个实现类:
package com.hiwei.spi.demo;

public class Cat implements Animal {
    @Override
    public void speak() {
        System.out.println("喵喵喵!");
    }
}
package com.hiwei.spi.demo;

public class Dog implements Animal {
    @Override
    public void speak() {
        System.out.println("汪汪汪!");
    }
}
  1. 在resources目录下创建meta-INF/services目录:

    创建以接口类路径命名的文件,文件中添加实现类路径:
com.hiwei.spi.demo.Cat
com.hiwei.spi.demo.Dog
  1. 使用
package com.hiwei.spi;

import com.hiwei.spi.demo.Animal;
import java.sql.SQLException;
import java.util.ServiceLoader;

public class SpiDemoApplication {

    public static void main(String[] args){
    	//会根据文件找到对应的实现类
        ServiceLoader load = ServiceLoader.load(Animal.class);
        //执行实现类方法
        for (Animal animal : load) {
            animal.speak();
        }
    }
}

执行结果:

上面我们可以看到java spi会帮助我们找到接口实现类。那么实际生产中怎么使用呢?
将上面的代码打成jar,然后在其它项目中引入,同样的目录下创建文件,并写上自己实现类的路径:

本项目实现类:

package com.example.demo;

import com.hiwei.spi.demo.Animal;

public class Pig implements Animal {
    @Override
    public void speak() {
        System.out.println("哼哼哼!");
    }
}

代码中,我们调用jar中的main方法:

package com.example.demo;

import com.hiwei.spi.SpiDemoApplication;

public class DemoApplication {

    public static void main(String[] args) {
        SpiDemoApplication.main(args);
    }
}

执行结果:

可以看见自定义的实现类也被执行了。在实际生产中,我们就可以使用java spi面向接口编程,实现可插拔。

SPI在JDBC中的应用

以最新的mysql-connector-java-8.0.27.jar为例


    mysql
    mysql-connector-java
    8.0.27

在使用JDBC连接数据库时,只需要使用:

DriverManager.getConnection("url", "username", "password");

DriverManager有静态方法:

    static {
        loadInitialDrivers();
        println("JDBC DriverManager initialized");
    }

看下loadInitialDrivers()方法,其中有:

AccessController.doPrivileged(new PrivilegedAction() {
            public Void run() {
				//获取Driver.class的实现类
                ServiceLoader loadedDrivers = ServiceLoader.load(Driver.class);
                Iterator driversIterator = loadedDrivers.iterator();

                
                try{
                    while(driversIterator.hasNext()) {
                        driversIterator.next();
                    }
                } catch(Throwable t) {
                // Do nothing
                }
                return null;
            }
        });

可以看见,会根据java spi获取Driver.class的实现类,可以在mysql-connector-java-8.0.27.jar下面看到,定义的文件:

程序会根据文件找到对应的实现类,并连接数据库。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/690938.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号