java SPI的实现,以及破坏双亲委派

SPI介绍

SPI

spi

spi破坏了双亲委派机制,主要是通过ServiceLoader类来实现,该类做了很多业务处理逻辑,包括驱动加载。从JDBC4.0之后,就不需要手动Class.forName来加载驱动了,代码如下:

 public static void main(String[] args) {
    
    
        try {
    
    
            Connection connection = DriverManager.getConnection("jdbc:mysql:///mysql","root","root");
            //打印出来是null,说明是BootStrapClassLoader加载的
            System.out.println(DriverManager.class.getClassLoader());
            Statement statement = connection.createStatement();
            String sql = "select Host from user";
            ResultSet resultSet = statement.executeQuery(sql);

            while (resultSet.next()) {
    
    
                String s = resultSet.getString("Host");
            }
        }  catch (SQLException throwables) {
    
    
            throwables.printStackTrace();
        }
    }

实际上Class.forName最终还是被调用了,不过是通过SPI来实现的,上面也说了SPI的核心就是ServiceLoader,这个类中还有一个内部类LazyIterator,serviceloader对象中 有个LazyIterator的字段,最终会调用到LazyIterator对象的nextService方法,该方法会去加载驱动
在这里插入图片描述

还可以看到加载驱动的加载器是appclassloader
在这里插入图片描述

为什么说SPI破坏了双亲委派

双亲委派的机制是说的是,加载一个类,层层向上委托,从appclassloader到extclassloader,再到bootstrapclassloader。然而在jdbc中,当我们加载DriverManager类时用的是BootStrapClassLoader(打印出来是null),它是最上层的父加载器,但是跟踪代码我们发现最终里面加载Driver时却是用的appclassloader,这说明了什么??? 父加载器居然反过来去调用子加载器去加载,这和双亲委派的定义刚好反过来了!所以说SPI破坏了双亲委派机制

参考

SPI介绍

猜你喜欢

转载自blog.csdn.net/chen462488588/article/details/113267781