package test; import org.apache.commons.pool.PoolableObjectFactory; import org.apache.commons.pool.impl.GenericObjectPool; import org.apache.log4j.Logger; import com.gargoylesoftware.htmlunit.BrowserVersion; import com.gargoylesoftware.htmlunit.NicelyResynchronizingAjaxController; import com.gargoylesoftware.htmlunit.WebClient; //http://blog.csdn.net/m13321169565/article/details/8081410 public class PooledClientFactory{ private static Logger log = Logger.getLogger(PooledClientFactory.class); private final static PooledClientFactory instance =new PooledClientFactory(); //另一種方案或許更爲合適——對象池化技術。 //基於Apache的commons-pool池 private final GenericObjectPool clientPool =new GenericObjectPool(); public static PooledClientFactory getInstance() { return instance; } public PooledClientFactory(){ //實現對象池的對象建立工廠接口 clientPool.setFactory(new PoolableObjectFactory() { // 建立對象實例,用於填充對象池。同時能夠分配這個對象適用的資源。 @Override public Object makeObject() throws Exception { log.info("爲線程 [ " + Thread.currentThread().getName()+ " ] 建立新的WebClient實例!"); WebClient webClient = new WebClient(BrowserVersion.FIREFOX_17); //設置webClient的相關參數 webClient.getCookieManager().setCookiesEnabled(true);// 開啓cookie管理 webClient.getOptions().setJavaScriptEnabled(true);// 開啓js解析 webClient.getOptions().setCssEnabled(false); // 當出現Http error時,程序不拋異常繼續執行 webClient.getOptions().setThrowExceptionOnFailingStatusCode(false); // 防止js語法錯誤拋出異常 webClient.getOptions().setThrowExceptionOnScriptError(false); // js運行錯誤時,是否拋出異常 webClient.getOptions().setTimeout(10000); // 默認是false, 設置爲true的話不讓你的瀏覽行爲被記錄 webClient.getOptions().setDoNotTrackEnabled(false); // 設置Ajax異步處理控制器即啓用Ajax支持 webClient .setAjaxController(new NicelyResynchronizingAjaxController()); return webClient; } // 銷燬對象,銷燬對象池時被調用,鏈接池調用invalidateObject(obj)時被調用 @Override public void destroyObject(Object arg0) throws Exception { log.info("銷燬對象:" + arg0); WebClient client = (WebClient) arg0; client.closeAllWindows(); client = null; } // 查詢對象有效性,須要對象池設置setTestOnBorrow(true),無效對象將被destroy @Override public boolean validateObject(Object arg0) { log.info("檢查對象有效性:" + arg0); return true; } // 激活一個對象,從對象池獲取對象時被調用 @Override public void activateObject(Object arg0) throws Exception { log.info("激活對象:" + arg0); } // 掛起(鈍化)一個對象,將對象還給對象池時被調用 @Override public void passivateObject(Object arg0) throws Exception { log.info("掛起對象:" + arg0); } }); clientPool.setTestOnBorrow(true); //借出對象達到最大值的最大等待時間,5s等待時間事後拋出異常 //clientPool.setMaxWait(5000); //設置最大可借出數量,默認爲8 clientPool.setMaxActive(10); } public WebClient getClient() { try { return (WebClient)this.clientPool.borrowObject(); } catch (Exception e) { e.printStackTrace(); return null; } } public void returnClient(WebClient client) { try { this.clientPool.returnObject(client); } catch (Exception e) { e.printStackTrace(); } } //測試對象池 public static void main(String[] args) { try { //CursorableLinkedList //獲得池中空閒的對象數量,若是不可用返回負數 log.info(PooledClientFactory.getInstance().clientPool.getNumIdle()); //取出對象1 Object obj1= PooledClientFactory.getInstance().getClient(); //取出對象2 Object obj2= PooledClientFactory.getInstance().getClient(); //取出對象3 Object obj3= PooledClientFactory.getInstance().getClient(); //若是對象借出達到最大數量MaxActive,程序會一直等待有可用的對象(歸還的),也能夠經過DEFAULT_MAX_WAIT設置等待時間,默認爲-1一直等待 PooledClientFactory.getInstance().getClient(); PooledClientFactory.getInstance().getClient(); PooledClientFactory.getInstance().getClient(); PooledClientFactory.getInstance().getClient(); PooledClientFactory.getInstance().getClient(); PooledClientFactory.getInstance().getClient(); //歸還對象1 PooledClientFactory.getInstance().returnClient((WebClient) obj1); //獲得池中空閒的對象數量 log.info(PooledClientFactory.getInstance().clientPool.getNumIdle()); // 返回從池中借出的對象數量 log.info(PooledClientFactory.getInstance().clientPool.getNumActive()); //最大可借出數量 log.info(PooledClientFactory.getInstance().clientPool.getMaxActive()); //最大空閒數量 log.info(PooledClientFactory.getInstance().clientPool.getMaxIdle()); //最小空閒數量 log.info(PooledClientFactory.getInstance().clientPool.getMinIdle()); PooledClientFactory.getInstance().clientPool.clear(); PooledClientFactory.getInstance().clientPool.close(); //使用工廠建立一個對象 PooledClientFactory.getInstance().clientPool.getMaxActive(); } catch (Exception e) { e.printStackTrace(); } } }