双亲委派模型 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
zxCoder
V2EX    问与答

双亲委派模型

  •  
  •   zxCoder 2020-04-09 19:52:47 +08:00 2641 次点击
    这是一个创建于 2081 天前的主题,其中的信息可能已经有所发展或是发生改变。

    为什么网上都说 JDBC 各个数据库的 Driver 的加载就是破坏了双亲委派模型。

    比如这一段

    “ JDBC 之所以要破坏双亲委派模式是因为,JDBC 的核心在 rt.jar 中由启动类加载器加载,而其实现则在各厂商实现的的 jar 包中,根据类加载机制,若 A 类调用 B 类,则 B 类由 A 类的加载器加载,也就是说启动类加载器要加载 jar 包下的类,我们都知道这是不可能的 “

    我不能理解根据类加载机制,若 A 类调用 B 类,则 B 类由 A 类的加载器加载,也就是说启动类加载器要加载 jar 包下的类,我们都知道这是不可能的这句话,前半句和后半句有什么联系吗,我知道启动类加载器不能加载 jar 包下的类,那我们为什么一定要用启动类加载器呢?

    11 条回复    2020-04-10 13:38:44 +08:00
    falsemask
        1
    falsemask  
       2020-04-09 20:24:13 +08:00
    JDBC 在 rt.jar 包下,只能由 Bootstrap ClassLoader 加载,但是具体的实现类在 xxx.jar 中,这个 jar 没法用 Bootstrap ClassLoader 加载,需要用 Thread Context ClassLoader
    zxCoder
        2
    zxCoder  
    OP
       2020-04-09 21:11:13 +08:00
    @falsemask 那就用 Application ClassLoader 不行吗
    falsemask
        3
    falsemask  
       2020-04-09 21:29:54 +08:00
    @zxCoder JDBC 用的就是 Application ClassLoader,我没描述清楚,Thread Context ClassLoader 不是一个具体的类,是 Thread 的一个变量 private ClassLoader contextClassLoader,默认就是 Application ClassLoader,可以看下这个方法:java.sql.DriverManager#getConnection(java.lang.String, java.util.Properties, java.lang.Class<?>)
    zerozerone
        4
    zerozerone  
       2020-04-09 21:39:40 +08:00 via Android
    看不懂你在说啥
    zerozerone
        5
    zerozerone  
       2020-04-09 21:41:48 +08:00 via Android
    根据双亲委派,application class loader 先委托给自己的父加载器去加载 JDBC 实现,但是实现是在第三方 jar 包里的,必然加载不到,因此这里要绕过双亲委派,直接使用 application class loader 去加载实现类,就是在这里打破的双亲委派机制
    zerozerone
        6
    zerozerone  
       2020-04-09 21:47:12 +08:00 via Android   2
    /div>
    @zerozerone 我这里说错了 DriverManager 默认用自己的类加载器加载 JDBC,它自己的加载器是 bootstrap class loader,必然加载不到实现类,就抛异常了,因此需要从 thread context 里拿到 application class loader,用 application class loader 去直接加载实现类
    GM
        7
    GM  
       2020-04-09 21:54:38 +08:00
    “双亲委派”这个翻译极具误导性,实际上如果翻译好的话,要容易理解很多。
    mazai
        8
    mazai  
       2020-04-09 23:43:30 +08:00   1
    因为 Driver 这个接口就是被启动类加载器所加载的,要使用具体实现则需要厂商的 jar 包,但是启动类加载器是无法加载 classpath 下的 jar 包,所以就引入了一个上下文类加载器( context classloader )来加载,默认情况下上下文类加载器就是我们的应用类加载器( app classloader ),应用类加载器显然是可以加载 classpath 下的 jar 包的。即打破了双亲委派的机制。
    zxCoder
        9
    zxCoder  
    OP
       2020-04-10 08:54:07 +08:00
    @falsemask 我理解是比如 JDBC
    原来是需要 Class.forName(); DriverManager.getConnection(); 这里没有嵌套关系,所以一个用 Application 加载器,一共用 bootstrap 加载器。

    然后 JDBC4.0 后,可以直接 DriverManager.getConnection(); 里面就自动调用了 Class.forName(); 有嵌套的关系,所以里面的 Class.forName 就得用外面的 Bootstrap 加载器来加载,所以才不行得用线程上下文加载器。
    falsemask
        10
    falsemask  
       2020-04-10 09:41:19 +08:00
    @zxCoder 我和你理解的一样,引入了 SPI 机制之后不需要手写 Class.forName(),需要用 context Classloader 来加载三方 jar 的类
    zxCoder
        11
    zxCoder  
    OP
       2020-04-10 13:38:44 +08:00
    @falsemask 谢谢 比较清楚了
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     1387 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 25ms UTC 16:42 PVG 00:42 LAX 08:42 JFK 11:42
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86