处事提供者框架中有四个重要的组件:
JDBC的实现就是一个处事者提供框架应用的典规范子。
JDBC与处事者提供框架
JDBC中的各脚色
JDBC的实现中包括有处事提供者接口,详细如下:
详细实现
处事接口:Connection
Connection即为数据库毗连处事,没什么非凡的,留意接口的多担任:
public interface Connection extends Wrapper, AutoCloseable { … }
处事提供者接口:Driver
Driver生成Connection处事:
public interface Driver { … Connection connect(String url, java.util.Properties info) throws SQLException; … }
记着Driver#connect()要领,昆山软件开发,后头还接见到。
提供者注册API:DriverManager.registerDriver()要领
处事的提供者实现Driver类,通过DriverManager.registerDriver()将处事提供者的实例注册到DriverManager中:
public class DriverManager { … public static synchronized void registerDriver(java.sql.Driver driver) throws SQLException { registerDriver(driver, null); } … public static synchronized void registerDriver(java.sql.Driver driver, DriverAction da) throws SQLException { /* Register the driver if it has not already been added to our list */ if(driver != null) { registeredDrivers.addIfAbsent(new DriverInfo(driver, da)); } else { // This is for compatibility with the original DriverManager throw new NullPointerException(); } println("registerDriver: " + driver); } … }
详细的注册行为由处事提供者提倡。MySQL的Driver实现com.mysql.jdbc.Driver为例:
public class Driver extends NonRegisteringDriver implements java.sql.Driver { … static { try { java.sql.DriverManager.registerDriver(new Driver()); } catch (SQLException E) { throw new RuntimeException("Can't register driver!"); } } … public Driver() throws SQLException { // Required for Class.forName().newInstance() } … }
可知,在第一次加载com.mysql.jdbc.Driver时,com.mysql.jdbc.Driver会操作静态代码块挪用提供者注册API DriverManager.registerDriver()。
处事会见API:DriverManager.getConnection()要领
注册处事提供者的实例后,处事提供者就可以或许通过框架提供处事。详细来说,可通过静态工场要领DriverManager.getConnection()提供Connection处事,底层是通过Driver接口的实现类实现的:
public class DriverManager { … public static Connection getConnection(String url) throws SQLException { java.util.Properties info = new java.util.Properties(); return (getConnection(url, info, Reflection.getCallerClass())); } … // Worker method called by the public getConnection() methods. private static Connection getConnection( … for(DriverInfo aDriver : registeredDrivers) { // If the caller does not have 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()); } } … } … }
留意这里的定名方法getConnection,昆山软件开发,今朝的实现中,每次返回的是新的Connection实例,感受叫做newConnection更得当。不知道为什么这样定名。
这里的逻辑很简朴,昆山软件开发,遍历所有已注册的Driver实现类,选择第一个可用的Driver建设Connection。还记得Driver#connect()要领吗?aDriver.driver.connect一句中,由底层Driver完成Connection的建设。