服务提供者框架中有四个重要的组件:
JDBC的实现就是一个服务者提供框架应用的典型例子。
JDBC的实现中包含有服务提供者接口,具体如下:
Connection即为数据库连接服务,没什么特殊的,注意接口的多继承:
- public
- interface
- Connection
- extends
- Wrapper
- ,
- AutoCloseable
- {
- …
- }
Driver生成Connection服务:
- public interface Driver {
- …
- Connection connect(String url, java.util.Properties info)
- throws SQLException;
- …
- }
记住Driver#connect()方法,后面还会见到。
服务的提供者实现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()。
注册服务提供者的实例后,服务提供者就能够通过框架提供服务。具体来说,可通过静态工厂方法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()方法吗?
一句中,由底层Driver完成Connection的创建。
- aDriver.driver.connect
done
来源: https://juejin.im/post/59ffbe8ef265da4309448ae2