欢迎访问昆山宝鼎软件有限公司网站! 设为首页 | 网站地图 | XML | RSS订阅 | 宝鼎邮箱 | 宝鼎售后问题提交 | 后台管理


新闻资讯

MENU

软件开发知识

da)); } else { // This is for compatibility with the origin

点击: 次  来源:昆山软开发 时间:2017-11-12

原文出处: 猴子007

处事提供者框架中有四个重要的组件:

  • 处事接口(Service Interface):由处事提供者实现,用来抽象处事提供者提供的处事。
  • 提供者注册API(Provider Registration API):系统用来注册实现,让客户端会见它们的。
  • 处事会见API(Service Access API):客户端用来获取处事的实例。
  • 处事提供者接口(Service Provider Interface):可选,由处事提供者实现,用来抽象处事提供者。
  • JDBC的实现就是一个处事者提供框架应用的典规范子。

    JDBC与处事者提供框架

    JDBC中的各脚色

    JDBC的实现中包括有处事提供者接口,详细如下:

  • 处事接口:Connection
  • 处事提供者接口:Driver
  • 提供者注册API:DriverManager.registerDriver()要领
  • 处事会见API:DriverManager.getConnection()要领
  • 详细实现

    处事接口: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的建设。