001package gu.simplemq.activemq; 002 003import java.net.URI; 004import java.util.Iterator; 005import java.util.Map; 006import java.util.Properties; 007import java.util.concurrent.ConcurrentMap; 008 009import javax.jms.Connection; 010 011import com.google.common.collect.Maps; 012 013import static org.apache.activemq.ActiveMQConnectionFactory.DEFAULT_BROKER_BIND_URL; 014import static com.google.common.base.Preconditions.checkNotNull; 015 016 017/** 018 * 延迟初始化的 {@link Connection}资源池(线程安全),使用方法:<br> 019 * 通过 {@link #getDefaultInstance()} 和getInstance(...)系列静态方法获取{@link ActivemqPoolLazy}实例<br> 020 * 通过{@link #apply()} 和 {@link #free()}方法实现{@link Connection}对象的申请和释放 021 * @author guyadong 022 * 023 */ 024public class ActivemqPoolLazys implements ActivemqConstants{ 025 /** {@link ActivemqPoolLazy }实例集合 */ 026 static final ConcurrentMap<URI,ActivemqPoolLazy> POOLS = Maps.newConcurrentMap(); 027 /** 028 * redis缺省连接参数<br> 029 * 这里没有使用guava的ImmutableMap,因为HashMap允许Value为null, ImmutableMap不允许 030 **/ 031 static final Properties DEFAULT_PARAMETERS = new Properties(){ 032 private static final long serialVersionUID = 1L; 033 { 034 put(ACON_BROKER_URL, DEFAULT_BROKER_BIND_URL); 035 } 036 }; 037 /** 默认连接池实例 */ 038 private static volatile ActivemqPoolLazy defaultInstance; 039 040 /** 041 * 返回默认实例,如果 {@link #defaultInstance}为null则创建默认实例 042 * @return 043 * @see #createDefaultInstance(Map) 044 */ 045 public static ActivemqPoolLazy getDefaultInstance() { 046 return null == defaultInstance 047 ? createDefaultInstance(null) 048 : defaultInstance; 049 } 050 051 /** 052 * 设置默认{@link ActivemqPoolLazy}实例<br> 053 * 仅当默认实例未初始化(为{@code null})且输入参数不为{@code null}时有效(返回{@code true}) 054 * 如果默认实例已经初始化,则输出警告日志,返回{@code false} 055 * @param poolLazy 为{@code null}返回{@code false} 056 * @return 设置成功返回{@code true},否则返回{@code false} 057 */ 058 public static boolean setDefaultInstance(ActivemqPoolLazy poolLazy) { 059 // double checking 060 if(null == defaultInstance){ 061 synchronized(ActivemqPoolLazys.class){ 062 if(null == defaultInstance && null != poolLazy){ 063 defaultInstance = poolLazy; 064 return true; 065 } 066 } 067 } 068 logger.warn("INVALID INVOCATION,default instance was initialized already before this invocation"); 069 return false; 070 } 071 072 /** 073 * 检测默认实例是否初始化 074 * @return 默认实例已经初始化则返回{@code true},否则返回false 075 */ 076 public static boolean defaultInstanceInitialized(){ 077 return defaultInstance != null; 078 } 079 /** 080 * 根据指定的连接参数创建默认实例,只能被调用一次(线程安全) 081 * @param props 082 * @return 083 */ 084 public static final ActivemqPoolLazy createDefaultInstance(Properties props){ 085 setDefaultInstance( getInstance(props)); 086 return defaultInstance; 087 } 088 089 static ActivemqPoolLazy createInstance(Properties props) { 090 return new ActivemqPoolLazy(props); 091 } 092 /** 093 * 查找在连接池对象集合中查找对应的匹配的对象,找不到就创建新实例 094 * @param props 095 * @return 096 */ 097 public static synchronized ActivemqPoolLazy getInstance(Properties props) { 098 // 查找在连接池对象集合中查找对应的匹配的对象,找不到就创建新实例 099 URI location = PropertiesHelper.AHELPER.getLocationlURI(props); 100 ActivemqPoolLazy found = POOLS.get(location); 101 return found == null ? createInstance(props) : found; 102 103 } 104 105 /** 106 * 根据uri查找在连接池对象集合中查找对应的匹配的对象,找不到就创建新实例 107 * @param uri 108 * @return 109 */ 110 public static ActivemqPoolLazy getInstance(URI uri) { 111 Properties props = new Properties(); 112 props.setProperty(ACON_BROKER_URL, checkNotNull(uri,"uri is null").toString()); 113 return getInstance(props); 114 } 115 116 public static ActivemqPoolLazy getInstanceByURI(String uri) { 117 return getInstance(URI.create(uri)); 118 } 119 /** 120 * 关闭并删除所有资源池中的{@link ActivemqPoolLazy}实例 121 */ 122 public synchronized static void closeAll(){ 123 for(Iterator<ActivemqPoolLazy> itor = POOLS.values().iterator();itor.hasNext();){ 124 ActivemqPoolLazy p = itor.next(); 125 itor.remove(); 126 p.close(); 127 } 128 } 129}