这篇博文,是对于享元模式的综合应用,如果你还不了解享元模式,那请先google一下。
案例:用享元模式来实现一个数据库连接池
抽象享元类:数据库连接池
public interface DbConnectionPool {
//1产生连接池,初始化连接池
public void initConnPool() throws SQLException;
//2设定打开或者关闭连接池
public void setConnWitch(String onOrOff) throws SQLException;
//3设定连接池中存放连接的数目
public void setMaxConns(int numConnections) throws Exception;
//4从连接池中获取连接
public Connection getConnection() throws SQLException;
//5将连接返回给连接池
public void returnConnection() throws SQLException;
//6销毁连接池
public void destroyConnPool() throws SQLException;
}
享元实现类:数据库连接池实现类
public class DbConnectionPoolImp implements DbConnectionPool {
private String DB_DRIVER="com.mysql.jdbc.Driver";
private String DB_USER="root";
private String DB_PASSWORD="";
private String DATASRC_URL="jdbc:mysql";
final static int defaultMaxConnection=10;
private List freeConnections;
private Map busyConnections;
private int maxConnection;
//构造函数1
public DbConnectionPoolImp(int numConnections){
maxConnection=numConnections;
freeConnections=null;
busyConnections=null;
}
public DbConnectionPoolImp(){
maxConnection=defaultMaxConnection;
freeConnections=null;
busyConnections=null;
}
//构造函数2
public void initConnPool() throws SQLException {
try {
freeConnections=new ArrayList(maxConnection);
busyConnections=new HashMap(maxConnection);
//创建连接
Class.forName(DB_DRIVER);
for(int i=0;i<maxConnection;i++){
Connection connection =
DriverManager.getConnection(DATASRC_URL, DB_USER, DB_PASSWORD);
freeConnections.add(connection);
}
} catch (Exception e) {
//如果有异常,说明初始化任务失败!一定要将所有连接置空!
freeConnections=null;
busyConnections=null;
throw new SQLException(e);
}
}
//设置连接池开关
public void setConnWitch(String onOrOff) throws SQLException {
try {
if("ON".equalsIgnoreCase(onOrOff)){
initConnPool();
}else if("OFF".equalsIgnoreCase(onOrOff)){
destroyConnPool();
}
} catch (Exception e) {
e.printStackTrace();
}
}
//设置连接池最大连接数
public void setMaxConns(int numConnections) throws Exception{
if(numConnections<=0){
throw new Exception("你传进来的大小有问题!亲!");
}
maxConnection=numConnections;
}
//从连接池中得到连接!
public synchronized Connection getConnection() throws SQLException {
if (freeConnections == null)
throw new SQLException("连接池还没有被创立");
try {
if(freeConnections.size()==0)
wait();
} catch (Exception e) {
e.printStackTrace();
}
//作者:获取空闲连接池
Connection conn=(Connection) freeConnections.get(0);
freeConnections.remove(0);
busyConnections.put(Thread.currentThread(), conn);
return conn;
}
//将空闲的连接返回到List freeConnections,方便管理
public synchronized void returnConnection() throws SQLException {
Connection conn=(Connection) busyConnections.get(Thread.currentThread());
if(conn==null){
throw new SQLException("没有发现繁忙池中有连接");
}
busyConnections.remove(Thread.currentThread());
//讲已经返回的连接重新放回空闲池中
freeConnections.add(conn);
notify();
}
//销毁连接池
public void destroyConnPool() throws SQLException {
if(busyConnections!=null){
Set set=busyConnections.entrySet();
Iterator iterator =set.iterator();
while(iterator.hasNext()){
Map.Entry entry=(Entry) iterator.next();
Connection conn=(Connection) entry.getValue();
conn.close();
}
//最后千万记得弄他为空!
busyConnections=null;
}
if(freeConnections!=null){
for (int i = 0; i < freeConnections.size(); i++) {
Connection conn=(Connection) freeConnections.get(i);
conn.close();
}
freeConnections=null;
}
}
}
享元工厂类:对数据库连接池管理
public class DbConnectionManager {
private static DbConnectionManager instance = new DbConnectionManager();
//存放所有的连接池,其中有mysql连接池,oracle连接池,sql server连接池等等!
private static Map connPool=new HashMap();
//返回唯一的实例
public static synchronized DbConnectionManager getInstance(){
return instance;
}
//防止其他对象创建
private DbConnectionManager(){}
//初始化连接池管理器
public void init(int nunberMax) throws Exception{
createPools(nunberMax);
}
/*
* 根据名称从Map中获取连接!!!注意,不是获取连接池
*/
public Connection getConnection(String name){
Connection conn=null;
try {
DbConnectionPool pool = (DbConnectionPool) connPool.get(name);
if(pool!=null){
conn=pool.getConnection();
}
} catch (Exception e) {
e.printStackTrace();
}
return conn;
}
//将连接返回给连接池
/**
* 这个方法明显有问题!传入的参数conn根本用不到
* @param name 连接池名字
* @param conn 连接
*/
public static void returnConnection(String name,Connection conn){
try {
DbConnectionPool pool=(DbConnectionPool) connPool.get(name);
if(pool!=null){
pool.returnConnection();
}
} catch (Exception e) {
e.printStackTrace();
}
}
//关闭所有连接
public static void release(){
try {
Set set=connPool.entrySet();
Iterator iterator =set.iterator();
//遍历所有的连接池!
while(iterator.hasNext()){
Map.Entry entry=(Entry) iterator.next();
DbConnectionPool pool=(DbConnectionPool) entry.getValue();
//关闭连接池
pool.setConnWitch("OFF");
}
} catch (Exception e) {
e.printStackTrace();
}
}
//创建连接池
public static void createPools(int numberMax) throws Exception{
DbConnectionPool pool=new DbConnectionPoolImp();
pool.setMaxConns(numberMax);
try {
//表示创建连接池
pool.setConnWitch("on");
//将创建后的连接池放在Map中,进行统一的管理
connPool.put("mysql",pool);
} catch (Exception e) {
e.printStackTrace();
}
}
}
成事在人,某事在天,大家加油!