关于java类加载器的几点思考

    引用文章 http://www.ibm.com/developerworks/cn/java/j-lo-classloader/
JDK提供三种类加载器来加载java类和一个特殊的上下文加载器,详情可参照上面的链接。本文主要讨论下面两点疑问:(这个也是我阅读上面文章后引发的思考)
1.java spi和具体第三方实现之间的联系是怎么实现的;
2. jdbc中为何要使用Class.forName方法进行注册;
进入正题:
1.java spi和具体第三方实现之间的联系是怎么实现的
java核心类(jdk)定义了一些服务接口 大都提供了默认实现(比如javax.xml),就拿javax.xml来说 如果我们不想使用sun的默认实现 想改用apache的第三方实现 如何操作?顺便提一下:javax.xml.parsers.DocumentBuilderFactory的默认实现是com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryIm pl
而我们要替换的实现是org.apache.xerces.jaxp.DocumentBuilderFactoryIm pl
做法有好几种,不过本质上一样的, 都是配置系统property中的键值 这里可以参照这篇博文:
但是这里就涉及了一个问题 apache的实现是有系统classloader加载的
而javax是由引导classloader加载的,按照类加载的代理模式,在实例化的时候 即调用DocumentBuilderFactory的newInstance方法的时候会找不到org.apache.xerces.jaxp.DocumentBuilderFactoryIm pl的类定义
为解决这种冲突,sun引入了上下文加载器 通过查阅源代码可以了解到 javax.xml.parsers.*中使用上下文加载器装入org.apache.xerces.jaxp.DocumentBuilderFactoryIm pl的class.这样就解决了类加载器的代理模式中跟spi设计之间的冲突
顺便提一点:如果没有上下文加载器的话 单纯按照java类加载器的代理模式 核心类是无法看到非核心类的定义的 当然也无法进行类初始化
2.jdbc中为何要使用Class.forName方法进行注册
使用jdbc进行数据库连接时,要在获取connection对象前进行驱动类的注册,调用Class.forName('驱动类') 这是为何呢 这里可以参照博文: http://www.cnblogs.com/zemliu/archive/2012/11/01/2750348.html
通过查阅驱动类源代码可以知道:mysql的驱动类中有块static代码块 java.sql.DriverManager.registerDriver() 
我们调用class.forName方法装载driver类会调用此static代码块 将该驱动类注册到driverManager,然后在drivermanager中使用上下文加载器进行该驱动类的加载和相关对象的实例化 当然这里可以使用其他的手段进行驱动类注册 可以参照上面第一点
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值