c3p0的DriverManagerDataSource源代码看单例
2015-06-30 00:25
417 查看
通过它看单例:
======================================================================
public Connection getConnection(String username, String password) throws SQLException { ensureDriverLoaded(); Connection out = driver().connect( jdbcUrl, overrideProps(username, password) ); if (out == null) throw new SQLException("Apparently, jdbc URL '" + jdbcUrl + "' is not valid for the underlying " + "driver [" + driver() + "]."); return out; } private synchronized void ensureDriverLoaded() throws SQLException { try { if (! isDriverClassLoaded()) { if (driverClass != null) Class.forName( driverClass ); setDriverClassLoaded( true ); } } catch (ClassNotFoundException e) { if (logger.isLoggable(MLevel.WARNING)) logger.log(MLevel.WARNING, "Could not load driverClass " + driverClass, e); } } private synchronized boolean isDriverClassLoaded() { return driver_class_loaded; } boolean driver_class_loaded = false;
======================================================================
/* * Distributed as part of c3p0 v.0.9.5.1 * * Copyright (C) 2015 Machinery For Change, Inc. * * Author: Steve Waldman <swaldman@mchange.com> * * This library is free software; you can redistribute it and/or modify * it under the terms of EITHER: * * 1) The GNU Lesser General Public License (LGPL), version 2.1, as * published by the Free Software Foundation * * OR * * 2) The Eclipse Public License (EPL), version 1.0 * * You may choose which license to accept if you wish to redistribute * or modify this work. You may offer derivatives of this work * under the license you have chosen, or you may provide the same * choice of license which you have been offered here. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * You should have received copies of both LGPL v2.1 and EPL v1.0 * along with this software; see the files LICENSE-EPL and LICENSE-LGPL. * If not, the text of these licenses are currently available at * * LGPL v2.1: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * EPL v1.0: http://www.eclipse.org/org/documents/epl-v10.php * */ package com.mchange.v2.c3p0; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.PrintWriter; import java.util.Properties; import java.sql.Connection; import java.sql.Driver; import java.sql.DriverManager; import java.sql.SQLException; import javax.sql.DataSource; import com.mchange.v2.sql.SqlUtils; import com.mchange.v2.log.MLevel; import com.mchange.v2.log.MLog; import com.mchange.v2.log.MLogger; import com.mchange.v2.c3p0.cfg.C3P0Config; import com.mchange.v2.c3p0.impl.DriverManagerDataSourceBase; public final class DriverManagerDataSource extends DriverManagerDataSourceBase implements DataSource { final static MLogger logger; static { logger = MLog.getLogger( DriverManagerDataSource.class ); // some drivers are not robust to simultanous attempts to // load. if our driver will be preloaded by the DriverManager class, // get it over with before we try anything try { Class.forName( "java.sql.DriverManager" ); } catch ( Exception e ) { String msg = "Could not load the DriverManager class?!?"; if ( logger.isLoggable( MLevel.SEVERE ) ) logger.log( MLevel.SEVERE, msg ); throw new InternalError( msg ); } } //MT: protected by this' lock Driver driver; //MT: protected by this' lock boolean driver_class_loaded = false; public DriverManagerDataSource() { this( true ); } public DriverManagerDataSource(boolean autoregister) { super( autoregister ); setUpPropertyListeners(); String user = C3P0Config.initializeStringPropertyVar("user", null); String password = C3P0Config.initializeStringPropertyVar("password", null); if (user != null) this.setUser( user ); if (password != null) this.setPassword( password ); } private void setUpPropertyListeners() { PropertyChangeListener driverClassListener = new PropertyChangeListener() { public void propertyChange( PropertyChangeEvent evt ) { if ( "driverClass".equals( evt.getPropertyName() ) ) { synchronized (DriverManagerDataSource.this) { setDriverClassLoaded( false ); // guard against setting to empty String or whitespace values. // JMX clients sometimes (unfortunately) represent null properties as blank fields, then update them to empty or whitespace Strings. if ( driverClass != null && driverClass.trim().length() == 0 ) //an empty String or all whitespace name driverClass = null; } } } }; this.addPropertyChangeListener( driverClassListener ); } private synchronized boolean isDriverClassLoaded() { return driver_class_loaded; } private synchronized void setDriverClassLoaded(boolean dcl) { this.driver_class_loaded = dcl; if (! driver_class_loaded) clearDriver(); // if we are changing to a yet-unloaded Driver class, the existing driver must be stale } private synchronized void ensureDriverLoaded() throws SQLException { try { if (! isDriverClassLoaded()) { if (driverClass != null) Class.forName( driverClass ); setDriverClassLoaded( true ); } } catch (ClassNotFoundException e) { if (logger.isLoggable(MLevel.WARNING)) logger.log(MLevel.WARNING, "Could not load driverClass " + driverClass, e); } } // should NOT be sync'ed -- driver() is sync'ed and that's enough // sync'ing the method creates the danger that one freeze on connect // blocks access to the entire DataSource public Connection getConnection() throws SQLException { ensureDriverLoaded(); Connection out = driver().connect( jdbcUrl, properties ); if (out == null) throw new SQLException("Apparently, jdbc URL '" + jdbcUrl + "' is not valid for the underlying " + "driver [" + driver() + "]."); return out; } // should NOT be sync'ed -- driver() is sync'ed and that's enough // sync'ing the method creates the danger that one freeze on connect // blocks access to the entire DataSource public Connection getConnection(String username, String password) throws SQLException { ensureDriverLoaded(); Connection out = driver().connect( jdbcUrl, overrideProps(username, password) ); if (out == null) throw new SQLException("Apparently, jdbc URL '" + jdbcUrl + "' is not valid for the underlying " + "driver [" + driver() + "]."); return out; } public PrintWriter getLogWriter() throws SQLException { return DriverManager.getLogWriter(); } public void setLogWriter(PrintWriter out) throws SQLException { DriverManager.setLogWriter( out ); } public int getLoginTimeout() throws SQLException { return DriverManager.getLoginTimeout(); } public void setLoginTimeout(int seconds) throws SQLException { DriverManager.setLoginTimeout( seconds ); } //overrides public synchronized void setJdbcUrl(String jdbcUrl) { //System.err.println( "setJdbcUrl( " + jdbcUrl + " )"); //new Exception("DEBUG STACK TRACE").printStackTrace(); super.setJdbcUrl( jdbcUrl ); clearDriver(); } //"virtual properties" public synchronized void setUser(String user) { String oldUser = this.getUser(); if (! eqOrBothNull( user, oldUser )) { if (user != null) properties.put( SqlUtils.DRIVER_MANAGER_USER_PROPERTY, user ); else properties.remove( SqlUtils.DRIVER_MANAGER_USER_PROPERTY ); pcs.firePropertyChange("user", oldUser, user); } } public synchronized String getUser() { // System.err.println("getUser() -- DriverManagerDataSource@" + System.identityHashCode( this ) + // " using Properties@" + System.identityHashCode( properties )); // new Exception("STACK TRACE DUMP").printStackTrace(); return properties.getProperty( SqlUtils.DRIVER_MANAGER_USER_PROPERTY ); } public synchronized void setPassword(String password) { String oldPass = this.getPassword(); if (! eqOrBothNull( password, oldPass )) { if (password != null) properties.put( SqlUtils.DRIVER_MANAGER_PASSWORD_PROPERTY, password ); else properties.remove( SqlUtils.DRIVER_MANAGER_PASSWORD_PROPERTY ); pcs.firePropertyChange("password", oldPass, password); } } public synchronized String getPassword() { return properties.getProperty( SqlUtils.DRIVER_MANAGER_PASSWORD_PROPERTY ); } private final Properties overrideProps(String user, String password) { Properties overriding = (Properties) properties.clone(); //we are relying on a defensive clone in our base class!!! if (user != null) overriding.put(SqlUtils.DRIVER_MANAGER_USER_PROPERTY, user); else overriding.remove(SqlUtils.DRIVER_MANAGER_USER_PROPERTY); if (password != null) overriding.put(SqlUtils.DRIVER_MANAGER_PASSWORD_PROPERTY, password); else overriding.remove(SqlUtils.DRIVER_MANAGER_PASSWORD_PROPERTY); return overriding; } private synchronized Driver driver() throws SQLException { //To simulate an unreliable DataSource... //double d = Math.random() * 10; //if ( d > 1 ) // throw new SQLException(this.getClass().getName() + " TEST of unreliable Connection. If you're not testing, you shouldn't be seeing this!"); //System.err.println( "driver() <-- " + this ); if (driver == null) { if (driverClass != null && forceUseNamedDriverClass) { if ( Debug.DEBUG && logger.isLoggable( MLevel.FINER ) ) logger.finer( "Circumventing DriverManager and instantiating driver class '" + driverClass + "' directly. (forceUseNamedDriverClass = " + forceUseNamedDriverClass + ")" ); try { driver = (Driver) Class.forName( driverClass ).newInstance(); this.setDriverClassLoaded( true ); } catch (Exception e) { SqlUtils.toSQLException("Cannot instantiate specified JDBC driver. Exception while initializing named, forced-to-use driver class'" + driverClass +"'", e); } } else driver = DriverManager.getDriver( jdbcUrl ); } return driver; } private synchronized void clearDriver() { driver = null; } private static boolean eqOrBothNull( Object a, Object b ) { return (a == b || (a != null && a.equals(b))); } // serialization stuff -- set up bound/constrained property event handlers on deserialization private static final long serialVersionUID = 1; private static final short VERSION = 0x0001; private void writeObject( ObjectOutputStream oos ) throws IOException { oos.writeShort( VERSION ); } private void readObject( ObjectInputStream ois ) throws IOException, ClassNotFoundException { short version = ois.readShort(); switch (version) { case VERSION: setUpPropertyListeners(); break; default: throw new IOException("Unsupported Serialized Version: " + version); } } // JDBC4 Wrapper stuff private boolean isWrapperForThis(Class<?> iface) { return iface.isAssignableFrom( this.getClass() ); } public boolean isWrapperFor(Class<?> iface) throws SQLException { return isWrapperForThis( iface ); } public <T> T unwrap(Class<T> iface) throws SQLException { if ( this.isWrapperForThis( iface ) ) return (T) this; else throw new SQLException(this + " is not a wrapper for or implementation of " + iface.getName()); } }
相关文章推荐
- 注解开发spring-aop 入门
- virtualtree 的使用(Delphi)
- 2015062908 - EffactiveJava笔记 - 第46条 foreach优先传统for循环(4)
- delphi中VirtualStringTree树使用方法之终结篇!
- Java enum的用法详解
- PHP文件包含漏洞详解
- Eclipse快捷键
- Python学习笔记 - 高阶函数
- Python学习笔记 - 高阶函数
- [Java]学习笔记,随笔【六】
- Delphi Virtual String Tree 基本用法
- [转载] Java NIO教程
- java实现——客户端登录
- 转 Delphi Invalidate的用法
- 2015062907 - EffactiveJava笔记 - 第46条 foreach优先传统for循环(3)
- ftp
- JAVA类图
- Chrony:一个类 Unix 系统上 NTP 客户端和服务器替代品
- python实现的简单FTP上传下载文件实例
- python实现线程池的方法