zoukankan      html  css  js  c++  java
  • 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包的结构如下

  • 相关阅读:
    每天一个设计模式(2):观察者模式
    每天一个设计模式(1):策略模式
    每天一个设计模式(0):设计模式概述
    常量池、栈、堆的比较
    常量池小结
    Java虚拟机体系结构分析
    Java并发(3):volatile及Java内存模型
    第一题:Big Countries
    22 高级SQL特性
    21 使用游标
  • 原文地址:https://www.cnblogs.com/jcli/p/2132211.html
Copyright © 2011-2022 走看看