您的位置:首页 > 编程语言

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());
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: