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}