jvm-sanbox详解-SPI机制

本文介绍了Java的SPI(Service Provider Interface)机制,用于在运行时动态加载服务提供者。详细解析了SPI如何加载MySQL驱动,包括在jar包的META-INF/services目录下定义服务提供者配置文件,并通过java.sql.DriverManager获取连接的过程。还讨论了SPI的使用限制,如运行时无法添加新服务,并介绍了简化SPI配置的@MetaInfServices注解。
摘要由CSDN通过智能技术生成

什么是SPI机制

SPI全称Service Provider Interface,是Java提供的一套用来被第三方实现或者扩展的接口。我们知道JDK代码提供了大量的方便的工具类给我们使用,JDK会对经常使用接口进行抽象统一。如链接数据库我们可以使用java.sql.DriverManager,但各种数据库的实现各自不同,所以为了给用户统一使用,屏蔽底层各自难懂的细节,我们这种SPI机制产生了。

mysql加载驱动

回想我们经常使用mysql的过程

0.配置文件:
    url: jdbc:mysql://localhost:3306/xxxxx?autoReconnect=true&useSSL=false&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
    username: xxx
    password: xxxxxx
1.注册驱动(现在已经不需要这一步加载了,写了也兼容不报错)
Class.forName("com.mysql.jdbc.Driver");
2.创建连接:
conn = (Connection) DriverManager.getConnection(url,username,password);
3.执行sql
stat = conn.createStatement();
String sql = "SELECT * FROM tb_person";
ResultSet rs = stat.executeQuery(sql);

让我们看看java.sql.DriverManager做了什么事情

//类初始化代码加载驱动
static {
   
    loadInitialDrivers();
    println("JDBC DriverManager initialized");
}


private static void loadInitialDrivers() {
   
    String drivers;
    try {
   
        //加载系统属性jdbc.drivers指定的drivers
        drivers = AccessController.doPrivileged(new PrivilegedAction<String>() {
   
            public String run() {
   
                return System.getProperty("jdbc.drivers");
            }
        });
    } catch (Exception ex) {
   
        drivers = null;
    }
    
    //如果driver驱动是Service Provider形式的,直接加载,并且替换上面系统属性指定方式
    AccessController.doPrivileged(new PrivilegedAction<Void>() {
   
        public Void run() {
   
            
            //使用ServiceLoader加载Driver
            ServiceLoader<Driver> loadedDrivers = ServiceLoader.load(Driver.class);
            Iterator<Driver> driversIterator = loadedDrivers.iterator();

            //遍历driver,driver有可能不存在或者配置错误,直接catch异常并忽略
            try{
   
                while(driversIterator.hasNext()) {
   
                    driversIterator.next();
                }
            } catch(Throwable t) {
   
            // Do nothing
            }
            return null;
        }
    });

    println("DriverManager.initialize: jdbc.drivers = " + drivers);

    if (drivers == null || drivers.equals("")) {
   
        return;
    }
    String[] driversList = drivers.split(":");
    println("number of Drivers:" + driversList.length);
    for (String aDriver : driversList) {
   
        try {
   
            println("DriverManager.Initialize: loading " + aDriver);
            //这里注意使用了系统类加载器加载驱动
            Class.forName(aDriver, true,
                    ClassLoader
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值