/** * Copyright (c) 2005-2010 springside.org.cn * * Licensed under the Apache License, Version 2.0 (the "License"); * * $Id: SpyMemcachedClient.java 1222 2010-09-14 16:44:57Z calvinxiu $ */ package org.springside.modules.memcached; import java.io.IOException; import java.util.Arrays; import java.util.Collection; import java.util.Map; import java.util.concurrent.Future; import net.spy.memcached.AddrUtil; import net.spy.memcached.CASResponse; import net.spy.memcached.CASValue; import net.spy.memcached.ConnectionFactoryBuilder; import net.spy.memcached.FailureMode; import net.spy.memcached.HashAlgorithm; import net.spy.memcached.MemcachedClient; import net.spy.memcached.ConnectionFactoryBuilder.Locator; import net.spy.memcached.ConnectionFactoryBuilder.Protocol; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.InitializingBean; /** * 对SpyMemcached Client的二次封装,提供常用的Get/GetBulk/Set/Delete/Incr/Decr函数的封装. * * 未提供封装的函数可直接调用getClient()取出Spy的原版MemcachedClient来使用. * * @author calvin */ public class SpyMemcachedClient implements InitializingBean, DisposableBean { private static Logger logger = LoggerFactory.getLogger(SpyMemcachedClient.class); private MemcachedClient memcachedClient; // 配置项 // private String memcachedNodes = "localhost:11211"; private boolean isBinaryProtocol = false; private boolean isConsistentHashing = true; private long operationTimeout = 1000; //default value in Spy is 1000ms // 初始,关闭函数 // @Override public void afterPropertiesSet() throws Exception { ConnectionFactoryBuilder cfb = new ConnectionFactoryBuilder(); cfb.setFailureMode(FailureMode.Redistribute); cfb.setDaemon(true); cfb.setProtocol(isBinaryProtocol ? Protocol.BINARY : Protocol.TEXT); if (isConsistentHashing) { cfb.setLocatorType(Locator.CONSISTENT); cfb.setHashAlg(HashAlgorithm.KETAMA_HASH); } cfb.setOpTimeout(operationTimeout); try { memcachedClient = new MemcachedClient(cfb.build(), AddrUtil.getAddresses(memcachedNodes)); } catch (IOException e) { logger.error("MemcachedClient initilization error: ", e); throw e; } } @Override public void destroy() throws Exception { if (memcachedClient != null) { memcachedClient.shutdown(); } } // Memcached访问函数 // public MemcachedClient getMemcachedClient() { return memcachedClient; } /** * Get方法, 转换结果类型并屏蔽异常,仅返回Null. */ @SuppressWarnings("unchecked") public <T> T get(String key) { try { return (T) memcachedClient.get(key); } catch (RuntimeException e) { logger.warn("Get from memcached server fail,key is " + key, e); return null; } } /** * GetBulk方法, 转换结果类型并屏蔽异常. */ @SuppressWarnings("unchecked") public <T> Map<String, T> getBulk(String... keys) { try { return (Map<String, T>) memcachedClient.getBulk(keys); } catch (RuntimeException e) { logger.warn("Get from memcached server fail,keys are " + Arrays.toString(keys), e); return null; } } /** * GetBulk方法, 转换结果类型并屏蔽异常. */ @SuppressWarnings("unchecked") public <T> Map<String, T> getBulk(Collection<String> keys) { try { return (Map<String, T>) memcachedClient.getBulk(keys); } catch (RuntimeException e) { logger.warn("Get from memcached server fail,keys are " + keys, e); return null; } } /** * Set方法. */ public Future<Boolean> set(String key, int expiredTime, Object value) { return memcachedClient.set(key, expiredTime, value); } /** * Delete方法. */ public Future<Boolean> delete(String key) { return memcachedClient.delete(key); } /** * 配合Check and Set的Get方法,转换结果类型并屏蔽异常. */ @SuppressWarnings("unchecked") public <T> CASValue<T> gets(String key) { try { return (CASValue<T>) memcachedClient.gets(key); } catch (RuntimeException e) { logger.warn("Get from memcached server fail,key is" + key, e); return null; } } /** * Check and Set方法. */ public CASResponse cas(String key, long casId, Object value) { return memcachedClient.cas(key, casId, value); } /** * Incr方法. */ public long incr(String key, int by, long defaultValue) { return memcachedClient.incr(key, by, defaultValue); } /** * Decr方法. */ public long decr(String key, int by, long defaultValue) { return memcachedClient.decr(key, by, defaultValue); } /** * 异步Incr方法, 不支持默认值, 若key不存在返回-1. */ public Future<Long> asyncIncr(String key, int by) { return memcachedClient.asyncIncr(key, by); } /** * 异步Decr方法, 不支持默认值, 若key不存在返回-1. */ public Future<Long> asyncDecr(String key, int by) { return memcachedClient.asyncDecr(key, by); } // 配置方法 // /** * 支持多节点, 以","分割. * eg. "localhost:11211,localhost:11212" */ public void setMemcachedNodes(String memcachedNodes) { this.memcachedNodes = memcachedNodes; } public void setBinaryProtocol(boolean isBinaryProtocol) { this.isBinaryProtocol = isBinaryProtocol; } public void setConsistentHashing(boolean isConsistentHashing) { this.isConsistentHashing = isConsistentHashing; } public void setOperationTimeout(long operationTimeout) { this.operationTimeout = operationTimeout; } }