DriverManager怎样查找当前Driver

记得刚学jdbc的时候,总有这么一条语句:

Class.forName("com.mysql.jdbc.Driver");

DriverManager.getConnection(url,name,password);


第一条语句是向DriverManager注册jdbc驱动,在加载Driver类时会执行里面的如下静态代码块:

static {

try {

java.sql.DriverManager.registerDriver(
new Driver());


}
catch (SQLException E) {

throw new RuntimeException("Can't register driver!");

}



}


但 是现在我们一般不用这条Class.forName语句了,之前我一直理所当然的认为能够这样做也不难,只要我们扫描CLASSPATH并判断哪些类 instanceof java.sql.Driver成立就可以了。可是再一想,如果依次扫描CLASSPATH并进行加载判断这个流程的话,显示是很SB的一种做法,应该会 很快OutOfMemoryError: PermGen space,呵呵。你说vm要load多少class meta信息。然后看了下jdk源码,并找了jar specification(http://download.oracle.com/javase/6/docs/technotes/guides/jar/jar.html#Service%20Provider),真相大白。

下面我就讲一下是怎么做到的。

假如现在有一个需求:我们向客户(也是开发)提供一个核心服务jar包,里面包括一个服务接口定义,如下:
package study.mybatis.jar;

public interface MyService {

public void doService();

}


客户端调用我们接口的代码如下:

Iterator itor = sun.misc.Service.providers(study.mybatis.jar.MyService.class);

while(itor.hasNext()){

Object obj
= itor.next();

if(obj instanceof MyService){

((MyService) obj).doService();

break;

}

}


客户不必关注我们具体的实现类,他只用Service.provider(类口的Class对象)方法就可以取到我们提供的具体实现类。
这 又是怎么做到的呢,这段代码怎么知道实例化那个MySerive接口的实现类?我们在生成jar包文件时只要在META-INF文件目录下创建一个名为 services的子文件目录,在services子目录里创建一个文本文件,名称为要提供的服务接口的全限定名, 如:study,mybatis.jar.MySerivce,里面写上一行你的实现类的名称,包括包名,如:
study.mybatis.jar.MyServiceImpl

现在整个jar包的结构如下

posted @ 2011-08-09 14:02  海鸟  阅读(633)  评论(0编辑  收藏  举报