connectionpoolmanager.java

来自「java编写的数据库连接池的源代码。包含有连接池的源码。」· Java 代码 · 共 637 行 · 第 1/2 页

JAVA
637
字号
			}
			catch (Exception e)
			{
				log("Unable to register JDBC driver: " + driverClassName + ", Exception: " + e);
			}
		}
	}

	/**
	 * Creates instances of ConnectionPool based on the properties.
	 * @param props the connection pool properties
	 */
	private void createPools(Properties props)
	{
		Iterator iter = props.keySet().iterator();
		while (iter.hasNext())
		{
			String name = (String)iter.next();
			if (name.endsWith(".url"))
			{
				String poolName = name.substring(0, name.lastIndexOf("."));
				String url = props.getProperty(poolName + ".url");
				if (url == null)
				{
					log("No URL specified for " + poolName);
					continue;
				}
				
				String user = props.getProperty(poolName + ".user");
				user = (user != null) ? user.trim() : user;
				String pass = props.getProperty(poolName + ".password");
				pass = (pass != null) ? pass.trim() : pass;
				String poolSize = props.getProperty(poolName + ".maxpool", "0").trim();
				String maxSize = props.getProperty(poolName + ".maxconn", "0").trim();
				String init = props.getProperty(poolName + ".init", "0").trim();
				String expiry = props.getProperty(poolName + ".expiry", "0").trim();
				String validator = props.getProperty(poolName + ".validator");
				String decoder = props.getProperty(poolName + ".decoder");
				validator = (validator != null) ? validator.trim() : validator;
				boolean noCache = props.getProperty(poolName + ".cache", "true").trim().equalsIgnoreCase("false");
				boolean async = props.getProperty(poolName + ".async", "false").trim().equalsIgnoreCase("true");
				boolean poolDebug = props.getProperty(poolName + ".debug", "false").trim().equalsIgnoreCase("true");

				// Construct properties object for pool if extra info supplied
				Properties poolProps = new Properties();
				String prefix = poolName + ".prop.";
				Iterator it = props.keySet().iterator();
				while (it.hasNext())
				{
					String s = (String)it.next();
					if (s.startsWith(prefix))
						poolProps.setProperty(s.substring(prefix.length()), props.getProperty(s));
				}
				if (!poolProps.isEmpty()  &&  user != null  &&  !user.equals(""))
				{
					poolProps.setProperty("user", user);
					poolProps.setProperty("password", pass);
				}
				else
					poolProps = null;

				// Validate poolsize
				int pSize, mSize, iSize, exp;
				try { pSize = Integer.valueOf(poolSize).intValue(); }
				catch (NumberFormatException nfe)
				{
					log("Invalid maxpool value " + poolSize + " for " + poolName);
					pSize = 0;
				}
				// Validate maxsize
				try { mSize = Integer.valueOf(maxSize).intValue(); }
				catch (NumberFormatException nfe)
				{
					log("Invalid maxconn value " + maxSize + " for " + poolName);
					mSize = 0;
				}
				// Validate init
				try { iSize = Integer.valueOf(init).intValue(); }
				catch (NumberFormatException nfe)
				{
					log("Invalid initsize value " + init + " for " + poolName);
					iSize = 0;
				}
				// Validate expiry
				try { exp = Integer.valueOf(expiry).intValue(); }
				catch (NumberFormatException nfe)
				{
					log("Invalid expiry value " + expiry + " for " + poolName);
					exp = 0;
				}

				// Validate pool size logic
				pSize = Math.max(pSize, 0);  // (ensure pSize >= 0)
				mSize = Math.max(mSize, 0);  // (ensure mSize >= 0)
				if (mSize > 0)  // (if mSize > 0, ensure mSize >= pSize)
					mSize = Math.max(mSize, pSize);
				iSize = Math.min(Math.max(iSize, 0), pSize);  // (ensure 0 <= iSize <= pSize)
				exp = Math.max(exp, 0);  // (ensure exp >= 0)

				// Create connection pool
				ConnectionPool pool = null;
				if (poolProps != null)
					pool = new ConnectionPool(poolName, pSize, mSize, (long)(exp * 1000), url, poolProps);
				else
					pool = new ConnectionPool(poolName, pSize, mSize, (long)(exp * 1000), url, user, pass);

				pool.setDateFormat(dateFormat);
				pool.setLog(getLogStream());
				if (poolDebug)
					log("Enabling debug info on pool " + poolName);
				pool.setDebug(poolDebug);
				if (noCache)
					log("Disabling caching on pool " + poolName);
				pool.setCaching(!noCache);
				if (async)
					log("Enabling asynchronous destruction on pool " + poolName);
				pool.setAsyncDestroy(async);

				// Setup connection validator for pool
				if (validator != null  &&  !validator.equals(""))
				{
					try
					{
						Object o = Class.forName(validator).newInstance();
						if (o instanceof ConnectionValidator)
							pool.setValidator((ConnectionValidator)o);
					}
					catch (Exception ex)
					{
						log("Unable to instantiate validator class for pool " + poolName + ": " + validator);
					}
				}

				// Setup password decoder for pool
				if (decoder != null  &&  !decoder.equals(""))
				{
					try
					{
						Object o = Class.forName(decoder).newInstance();
						if (o instanceof PasswordDecoder)
							pool.setPasswordDecoder((PasswordDecoder)o);
					}
					catch (Exception ex)
					{
						log("Unable to instantiate password decoder class for pool " + poolName + ": " + decoder);
					}
				}

				// Add new pool to collection, and show summary info
				pools.put(poolName, pool);
				String info = "pool=" + pool.getPoolSize() + ",max=" + pool.getMaxSize() + ",expiry=";
				info += pool.getExpiryTime() == 0 ? "none" : pool.getExpiryTime() + "ms";
				log("Initialized pool " + poolName + " (" + info + ")");

				// Setup initial connections in pool (spawns a thread)
				if (iSize > 0)
					pool.init(iSize);
			}
		}
	}

	/**
	 * Returns a connection pool.
	 * (This is only provided as a convenience method to allow fine-tuning in
	 * exceptional circumstances.)
	 * @param name pool name as defined in the properties file
	 * @return the pool or null
	 */
	public ConnectionPool getPool(String name)
	{
		if (released)
			throw new RuntimeException("Pool manager no longer valid for use");
		return (ConnectionPool)pools.get(name);
	}

	/**
	 * Returns all the current connection pools maintained by this manager.
	 * (This is only provided as a convenience method.)
	 * @return array of ConnectionPool objects
	 */
	public ConnectionPool[] getPools()
	{
		ConnectionPool[] x = new ConnectionPool[pools.size()];
		int a = 0;
		for (Enumeration e = pools.elements(); e.hasMoreElements();)
			x[a++] = (ConnectionPool)e.nextElement();
		return x;
	}

	/**
	 * Returns an open connection from the specified pool.
	 * If one is not available, and the max number of connections has not been
	 * reached, a new connection is created.
	 * @param name pool name as defined in the properties file
	 * @return the connection or null
	 */
	public Connection getConnection(String name) throws SQLException
	{
		if (released)
			throw new RuntimeException("Pool manager no longer valid for use");

		ConnectionPool pool = (ConnectionPool)pools.get(name);
		if (pool != null)
			return pool.getConnection();
		return null;
	}

	/**
	 * Returns an open connection from the specified pool.
	 * If one is not available, and the max number of connections has not been
	 * reached, a new connection is created. If the max number has been
	 * reached, waits until one is available or the specified time has elapsed.
	 * @param name pool name as defined in the properties file
	 * @param time number of milliseconds to wait
	 * @return the connection or null
	 */
	public Connection getConnection(String name, long time) throws SQLException
	{
		if (released)
			throw new RuntimeException("Pool manager no longer valid for use");

		ConnectionPool pool = (ConnectionPool)pools.get(name);
		if (pool != null)
			return pool.getConnection(time);
		return null;
	}

	/**
	 * Releases all resources for this ConnectionPoolManager, and deregisters
	 * JDBC drivers if necessary. Any connections still in use are forcibly closed.
	 */
	public synchronized void release()
	{
		// Don't release if client still active
		if (--clients != 0)
			return;
		// Set released flag to prevent check-out of new items
		released = true;

		Enumeration e = pools.elements();
		while (e.hasMoreElements())
		{
			ConnectionPool pool = (ConnectionPool)e.nextElement();
			pool.releaseForcibly();
		}

		// Check if drivers can be deregistered (only 1 manager left)
		if (managers.size() == 1)
		{
			e = drivers.elements();
			while (e.hasMoreElements())
			{
				Driver driver = (Driver)e.nextElement();
				try
				{
					DriverManager.deregisterDriver(driver);
					log("Deregistered JDBC driver " + driver.getClass().getName());
				}
				catch (SQLException sqle)
				{
					log(sqle, "Can't deregister JDBC driver: " + driver.getClass().getName());
				}
			}
		}

		// Close log
		super.close();
	}

	/**
	 * Returns whether this instance has been released (and therefore is unusable).
	 */
	public synchronized boolean isReleased() { return this.released; }

	/**
	 * Sets the validator class for connections.
	 * The same validator class is used for all pools held by this manager.
	 */
	public synchronized void setValidator(ConnectionValidator cv)
	{
		if (pools != null)
		{
			Enumeration e = pools.elements();
			while (e.hasMoreElements())
				((ConnectionPool)e.nextElement()).setValidator(cv);
		}
	}

	/**
	 * Overrides method in LogUtil to set log for pools as well.
	 */
	public void setLog(OutputStream out)
	{
		super.setLog(out);
		// Set log for all pools
		if (pools != null)
		{
			Enumeration e = pools.elements();
			while (e.hasMoreElements())
				((ConnectionPool)e.nextElement()).setLog(out);
		}
	}

	/**
	 * Overrides method in LogUtil to set log for pools as well.
	 */
	public void setLog(PrintStream ps)
	{
		super.setLog(ps);
		// Set log for all pools
		if (pools != null)
		{
			Enumeration e = pools.elements();
			while (e.hasMoreElements())
				((ConnectionPool)e.nextElement()).setLog(ps);
		}
	}
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?