How the JDBC driver is loaded

Source: Internet
Author: User
Tags postgresql try catch

Note: The source of this article: http://www.cnblogs.com/jiaoyiping/reprint please retain the source

JDBC defines a set of interfaces that the provider of the database product implements to provide its own database driver, which is a good example of interface-oriented programming, where you just need to replace the driver when you want to replace the database (the difference between the data types and SQL syntax of different databases is not considered here)

So how do you initialize a specific database (in PostgreSQL, for example)?

We will write the following code when using native JDBC:

Class.forName ("Org.postgresql.Driver");

Collection conn = drivermanager.getcollection ("URL", "username", "password");

What do these two lines of code do?

How does the drive load? We know that class.forname () causes initialization of the class (

1. Load the corresponding class file according to the fully qualified name of the class passed in,

2. Verify the bytecode and allocate storage space for the static domain of the class.

3. Set values for static properties, execute static blocks of code, etc.)

The registration of the driver is executed in the static code block , taking PostgreSQL9.3 's driver as an example:

 Public classDriverImplementsjava.sql.driver{//Make these public so they can is used in Setloglevel below     Public Static Final intDEBUG = 2;  Public Static Final intINFO = 1;  Public Static Final intOFF = 0; Private Static FinalLogger Logger =NewLogger (); Private Static BooleanLoglevelset =false; Private StaticTimer canceltimer=NULL; Static    {        Try        {            //moved the Registerdriver from the constructor//because some clients call the driver themselves (I know, as//my early JDBC work Did-and is based on the other examples). //placing it here, means that the driver was registered once only.            Java.sql.DriverManager.registerDriver (New Driver ());        }        Catch(SQLException e) {e.printstacktrace (); }    }

DriverManager's Register Method:

 Public Static synchronized void registerdriver (java.sql.Driver Driver)         throws SQLException {        null);    }
 Public Static synchronized voidRegisterdriver (java.sql.Driver Driver, Driveraction da)throwsSQLException {/*Register The driver if it has no already been added to our list*/        if(Driver! =NULL) {registereddrivers.addifabsent (Newdriverinfo (Driver, DA)); } Else {            //compatibility with the original DriverManager            Throw NewNullPointerException (); } println ("Registerdriver:" +driver); }

The Drivermanager.getcollection () method iterates through the drivers that have been registered to the system, calling the appropriate methods in the driver to get a true database connection.

    Private StaticConnection getconnection (String url, java.util.Properties info, Class<?> caller)throwsSQLException {/** When CALLERCL is null, we should check the application ' s * (which are invoking this class indirectly         * ClassLoader, so, the JDBC driver class outside Rt.jar * Can is loaded from here. */ClassLoader CALLERCL= Caller! =NULL? Caller.getclassloader ():NULL; synchronized(DriverManager.class) {            //Synchronize loading of the correct classloader.            if(CALLERCL = =NULL) {CALLERCL=Thread.CurrentThread (). Getcontextclassloader (); }        }        if(url = =NULL) {            Throw NewSQLException ("The URL cannot be null", "08001"); } println ("Drivermanager.getconnection (\" "+ URL +" \ ")"); //Walk through the loaded registereddrivers attempting to make a connection. //Remember The first exception that gets raised so we can reraise it.SQLException reason =NULL;  for(Driverinfo adriver:registereddrivers) {//If The caller does not has permission to load the driver then//Skip it.            if(isdriverallowed (Adriver.driver, CALLERCL)) {Try{println ("Trying" +ADriver.driver.getClass (). GetName ()); Connection Con=aDriver.driver.connect (URL, info); if(Con! =NULL) {                        //success!println ("getconnection returning" +ADriver.driver.getClass (). GetName ()); return(con); }                } Catch(SQLException ex) {if(Reason = =NULL) {Reason=ex; }                }            } Else{println ("Skipping:" +Adriver.getclass (). GetName ()); }        }        //If we got here nobody could connect.        if(Reason! =NULL) {println ("Getconnection failed:" +reason); Throwreason; } println ("Getconnection:no suitable driver found for" +URL); Throw NewSQLException ("No suitable driver found for" + URL, "08001"); }}

since the beginning of the JDBC4.0, Class.forName (""), can be omitted , because in DriverManager static code block will look for jdbc.drivers This system variable, Locate the appropriate driver and use Class.forName () to load it

The detailed code is as follows:

/**      * Load The initial JDBC drivers by checking the System property     * jdbc.properties and then use the {  @code  Serviceloader} mechanism     */    static  {         Loadinitialdrivers ();        println ("JDBC drivermanager initialized");    }
Private Static voidloadinitialdrivers () {String drivers; Try{Drivers= Accesscontroller.doprivileged (NewPrivilegedaction<string>() {                 PublicString Run () {return system.getproperty ("Jdbc.drivers");        }            }); } Catch(Exception ex) {drivers=NULL; }        //If The driver is packaged as a Service Provider, load it. //Get All the drivers through the ClassLoader//exposed as a java.sql.Driver.class service. //serviceloader.load () replaces the sun.misc.Providers ()accesscontroller.doprivileged (NewPrivilegedaction<void>() {             PublicVoid Run () {Serviceloader<Driver> loadeddrivers = Serviceloader.load (Driver.class); Iterator<Driver> Driversiterator =Loadeddrivers.iterator (); /*Load These drivers, so this they can be instantiated.  * It May is the case, the driver class may is not there * i.e. there is a packaged driver with the Service class * As implementation of Java.sql.Driver but the actual class * could be missin G. In this case a java.util.ServiceConfigurationError * 'll be thrown at runtime by the VM trying to Loca                 TE * and load the service. * * Adding a try catch block to catch those runtime errors * If driver not available in CL                 Asspath but it's * packaged as service and that service are there in classpath. */                Try{                     while(Driversiterator.hasnext ()) {driversiterator.next (); }                } Catch(Throwable t) {// do nothing                }                return NULL;        }        }); println ("DriverManager.initialize:jdbc.drivers =" +drivers); if(Drivers = =NULL|| Drivers.equals ("")) {            return; } string[] DriversList= Drivers.split (":"); println ("Number of Drivers:" +driverslist.length);  for(String adriver:driverslist) {Try{println ("DriverManager.Initialize:loading" +adriver); Class.forName (adriver, true , Classloader.getsystemclassloader ()); } Catch(Exception ex) {println ("DriverManager.Initialize:load failed:" +ex); }        }    }

How the JDBC driver is loaded

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.