001package gu.simplemq.activemq; 002 003import java.net.URI; 004import java.util.Properties; 005import javax.jms.Connection; 006import javax.jms.JMSException; 007 008import org.apache.activemq.pool.PooledConnectionFactory; 009 010import gu.simplemq.pool.BaseMQPool; 011import static gu.simplemq.activemq.ActivemqPoolLazys.POOLS; 012import static gu.simplemq.activemq.ActivemqPoolLazys.setDefaultInstance; 013/** 014 * 延迟初始化的 {@link Connection}资源池(线程安全),使用方法:<br> 015 * 通过 {@link #getDefaultInstance()} 和getInstance(...)系列静态方法获取{@link ActivemqPoolLazy}实例<br> 016 * 通过{@link #apply()} 和 {@link #free()}方法实现{@link Connection}对象的申请和释放 017 * @author guyadong 018 * 019 */ 020public class ActivemqPoolLazy extends BaseMQPool<Connection> implements ActivemqConstants{ 021 private final Properties parameters; 022 023 public Properties getParameters() { 024 return new Properties(parameters); 025 } 026 027 private volatile PooledConnectionFactory pool; 028 protected ActivemqPoolLazy (Properties props) { 029 this.parameters = PropertiesHelper.AHELPER.initParameters(props); 030 URI uri = PropertiesHelper.AHELPER.getLocationlURI(props); 031 POOLS.put(uri,this); 032 } 033 034 /** 035 * 将当前实例指定为默认实例 036 * @return 037 * @see #setDefaultInstance(ActivemqPoolLazy) 038 */ 039 public ActivemqPoolLazy asDefaultInstance(){ 040 setDefaultInstance(this); 041 return this; 042 } 043 private PooledConnectionFactory createPool(){ 044 URI uri = this.getCanonicalURI(); 045 PooledConnectionFactory pool = new PooledConnectionFactory(); 046 pool.setProperties(parameters); 047 logger.info("activemq pool initialized(连接池初始化) {} ",uri); 048 return pool; 049 } 050 051 @Override 052 public Connection borrow(){ 053 // double-checked locking 054 if(null == pool){ 055 synchronized (this){ 056 if(null == pool){ 057 pool = createPool(); 058 } 059 } 060 } 061 try { 062 return pool.createConnection(); 063 } catch (JMSException e) { 064 throw new RuntimeException(e); 065 } 066 } 067 068 @Override 069 public void release(Connection r) { 070 if (r != null){ 071 try { 072 r.close(); 073 } catch (JMSException e) { 074 throw new RuntimeException(e); 075 } 076 } 077 } 078 @Override 079 public URI getCanonicalURI(){ 080 return PropertiesHelper.AHELPER.getLocationlURI(parameters); 081 } 082 083 @Override 084 public void close(){ 085 // double check 086 if(pool != null){ 087 synchronized (this){ 088 if(pool != null){ 089 pool.stop(); 090 logger.info("discard activemq pool: {}",this); 091 pool = null; 092 closed = true; 093 } 094 } 095 } 096 } 097}