spi

实例:

 

 

一个接口

 

一个实现

 

一个配置

 

一个main:

 

源码:

 

成员

注意这里是Thread Context ClassLoader。

在线程初始化的时候,会取父线程的ClassLoader,全局没有的话 最后会是应用程序类加载器。

 

获取一个classLoader:

 

 

 

 

 

 

 

 

 

 

 

 

 

整体看下来好像没有这么神秘,在hasNext中还是用prefix拼了全限定名找到文件,然后用文件流读文件,找出文件中的全限定名,委托给双亲加载

来看一下为什么说jdbc破坏了双亲委派。我们看一下获取jdbc链接的方式:

 DriverManager.getConnection();
在加载DriverManager的时候:
可以看到这样一个静态块:

 

 

loadInitialDrivers中使用了sericeLoader去加载Driver.class的实现类。DriverManager本身的加载不会有什么问题。只是在DriverManager加载完之后进行初始化的时候,<clinit>执行loadInitialDrivers需要去加载Driver的实现类,但是就很尴尬的发现整个DriverManager是在rt.jar下由启动类加载器负责加载,我一个最顶级超类去加载已经不能 像应用程序类加载器那样双亲委派到到最顶级,加载不行在往下委托给孩子,我自己已经是顶级且委派给我自己,那么我只能加载lib下面的包中的类,但是Driver的实现类被厂商自己实现肯定是在用户类路径中的,我不得不拿到一个应用程序加载器类去帮我做这件事情,于是便有了ServiceLoader的使用

 

dubbo spi:

 

 

总体上使用方法如上。

看下实现源码:

 

缓存,还用多讲吗?往下看就完事了:

 

缓存缓存,全是缓存

 

 

 

emm看到这个classLoader大概知道会发生什么了

 

可以看到按行读取配置之后已经拿到了clazz了。那loadClass做了什么呢

 

好吧又是缓存。注意这里判断是否是WrapperClass是根据有参的构造方法来的。而普通的扩展点则要求无参的构造方法。

 

 在获得实例之后进行了IOC的注入:

 

结束,就这些

 

posted @ 2020-07-24 21:28  l2c  阅读(144)  评论(0)    收藏  举报