flea-frame-cache使用之Memcached接入

Memcached接入

1. 參考

flea-frame-cache使用之Memcached接入 源代碼java

2. 依賴

Memcached-Java-Client-3.0.2.jargit

<!-- Memcached相關 -->
<dependency>
    <groupId>com.whalin</groupId>
    <artifactId>Memcached-Java-Client</artifactId>
    <version>3.0.2</version>
</dependency>

spring-context-4.3.18.RELEASE.jargithub

<!-- Spring相關 -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>4.3.18.RELEASE</version>
</dependency>

spring-context-support-4.3.18.RELEASE.jar算法

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context-support</artifactId>
    <version>4.3.18.RELEASE</version>
</dependency>

3. 基礎接入

3.1 定義Flea緩存接口 --- IFleaCache

/**
 * <p> 自定義Cache接口類(主要定義了一些增刪改查的方法) </p>
 *
 * @author huazie
 */
public interface IFleaCache {

    /**
     * <p> 讀緩存 </p>
     *
     * @param key 數據鍵關鍵字
     * @return 數據值
     */
    Object get(String key);

    /**
     * <p> 寫緩存 </p>
     *
     * @param key   數據鍵關鍵字
     * @param value 數據值
     */
    void put(String key, Object value);

    /**
     * <p> 清空全部緩存 </p>
     */
    void clear();

    /**
     * <p> 刪除指定數據鍵關鍵字對應的緩存 </p>
     *
     * @param key 數據鍵關鍵字
     */
    void delete(String key);

    /**
     * <p> 獲取 記錄當前Cache全部數據鍵關鍵字 的Set集合 </p>
     *
     * @return 數據鍵key的集合
     */
    Set<String> getCacheKey();

    /**
     * <p> 獲取緩存所屬系統名 </p>
     *
     * @return 緩存所屬系統名
     */
    String getSystemName();
}

3.2 定義抽象Flea緩存類 --- AbstractFleaCache

/**
 * <p> 抽象Flea Cache類 </p>
 *
 * @author huazie
 */
public abstract class AbstractFleaCache implements IFleaCache {

    private final String name;  // 緩存數據主關鍵字

    private final long expiry;  // 有效期(單位:秒)

    protected CacheEnum cache;  // 緩存實現

    public AbstractFleaCache(String name, long expiry) {
        this.name = name;
        this.expiry = expiry;
    }

    @Override
    public Object get(String key) {
        Object value = null;
        try {
            value = getNativeValue(getNativeKey(key));
        } catch (Exception e) {
        }
        return value;
    }

    @Override
    public void put(String key, Object value) {
        if (ObjectUtils.isEmpty(value))
            return;
        try {
            putNativeValue(getNativeKey(key), value, expiry);
            // 將指定Cache的key添加到Set集合,並存於緩存中
            addCacheKey(key);
        } catch (Exception e) {
        }
    }

    @Override
    public void clear() {
        Set<String> keySet = getCacheKey();
        if (CollectionUtils.isNotEmpty(keySet)) {
            for (String key : keySet) {
                deleteNativeValue(getNativeKey(key));
            }
            // 刪除 記錄當前Cache全部數據鍵關鍵字 的緩存
            deleteCacheAllKey();
        }
    }

    @Override
    public void delete(String key) {
        try {
            deleteNativeValue(getNativeKey(key));
            // 從 記錄當前Cache全部數據鍵關鍵字 的緩存中 刪除指定數據鍵關鍵字key
            deleteCacheKey(key);
        } catch (Exception e) {
        }
    }

    /**
     * <p> 將指定數據鍵關鍵字{@code key}記錄到當前Cache全部數據鍵關鍵字的緩存中 </p>
     *
     * @param key 指定Cache的數據鍵關鍵字
     */
    private void addCacheKey(String key) {
        Set<String> keySet = getCacheKey();
        if (CollectionUtils.isEmpty(keySet)) {
            keySet = new HashSet<>();
        }
        if (!keySet.contains(key)) { // 只有其中不存在,才從新設置
            keySet.add(key);
            putNativeValue(getNativeCacheKey(name), keySet, CommonConstants.NumeralConstants.ZERO);
        }
    }

    /**
     * <p> 從 記錄當前Cache全部數據鍵關鍵字 的緩存中 刪除指定數據鍵關鍵字{@code key} </p>
     *
     * @param key 指定Cache的數據鍵關鍵字
     */
    private void deleteCacheKey(String key) {
        Set<String> keySet = getCacheKey();
        if (CollectionUtils.isNotEmpty(keySet)) {
            // 存在待刪除的數據鍵關鍵字
            if (keySet.contains(key)) {
                if (CommonConstants.NumeralConstants.INT_ONE == keySet.size()) {
                    deleteCacheAllKey(); // 直接將記錄當前Cache全部數據鍵關鍵字的緩存從緩存中清空
                } else {
                    // 將數據鍵關鍵字從Set集合中刪除
                    keySet.remove(key);
                    // 從新覆蓋當前Cache全部數據鍵關鍵字的緩存信息
                    putNativeValue(getNativeCacheKey(name), keySet, CommonConstants.NumeralConstants.ZERO);
                }
            }
        }
    }

    /**
     * <p> 刪除 記錄當前Cache全部數據鍵關鍵字 的緩存 </p>
     */
    private void deleteCacheAllKey() {
        try {
            deleteNativeValue(getNativeCacheKey(name));
        } catch (Exception e) {
        }
    }

    @Override
    @SuppressWarnings(value = "unchecked")
    public Set<String> getCacheKey() {
        Set<String> keySet = null;
        Object keySetObj = getNativeValue(getNativeCacheKey(name));
        if (ObjectUtils.isNotEmpty(keySetObj) && keySetObj instanceof Set) {
            keySet = (Set<String>) keySetObj;
        }
        return keySet;
    }

    /**
     * <p> 獲取緩存值 </p>
     *
     * @param key 緩存數據鍵關鍵字
     * @return 緩存值
     */
    public abstract Object getNativeValue(String key);

    /**
     * <p> 添加緩存數據 </p>
     *
     * @param key    緩存數據鍵關鍵字
     * @param value  緩存值
     * @param expiry 失效時間(單位:秒)
     */
    public abstract void putNativeValue(String key, Object value, long expiry);

    /**
     * <p> 刪除指定緩存數據 </p>
     *
     * @param key 緩存數據鍵關鍵字
     */
    public abstract void deleteNativeValue(String key);

    /**
     * <p> 獲取緩存所屬系統名 </p>
     *
     * @return 緩存所屬系統名
     */
    public abstract String getSystemName();

    /**
     * <p> 獲取實際存儲的緩存鍵(緩存所屬系統名 + 緩存名(緩存主關鍵字) + 緩存數據鍵(緩存數據關鍵字)) </p>
     *
     * @param key 緩存數據鍵關鍵字
     * @return 實際存儲的緩存鍵
     */
    private String getNativeKey(String key) {
        return StringUtils.strCat(getNativeCacheKey(name), CommonConstants.SymbolConstants.UNDERLINE, key);
    }

    /**
     * <p> 獲取緩存主鍵(包含緩存所屬系統名 + 緩存名(緩存主關鍵字))  </p>
     *
     * @param name 緩存名(緩存主關鍵字)
     * @return 緩存主鍵(緩存所屬系統名 + 緩存名(緩存主關鍵字))
     */
    protected String getNativeCacheKey(String name) {
        return StringUtils.strCat(getSystemName(), CommonConstants.SymbolConstants.UNDERLINE, name);
    }

    // ...省略一些get方法
}

該類實現了IFleaCache接口,同時定義了三個抽象方法 :spring

public abstract Object getNativeValue(String key);

    public abstract void putNativeValue(String key, Object value, long expiry);

    public abstract void deleteNativeValue(String key);

這三個抽象方法由子類實現具體的讀,寫,刪除緩存的原始操做緩存

3.3 定義MemCached Flea緩存類 --- MemCachedFleaCache

該類繼承 AbstractFleaCache,實現Memcached緩存的接入使用;bash

/**
 * <p> MemCached Flea緩存類 </p>
 *
 * @author huazie
 */
public class MemCachedFleaCache extends AbstractFleaCache {

    private final MemCachedClient memCachedClient;  // MemCached客戶端

    /**
     * <p> 帶參數的構造方法,初始化MemCached Flea緩存類 </p>
     *
     * @param name            緩存主關鍵字
     * @param expiry          失效時長
     * @param memCachedClient MemCached客戶端
     */
    public MemCachedFleaCache(String name, long expiry, MemCachedClient memCachedClient) {
        super(name, expiry);
        this.memCachedClient = memCachedClient;
        cache = CacheEnum.MemCached;
    }

    @Override
    public Object getNativeValue(String key) {
        return memCachedClient.get(key);
    }

    @Override
    public void putNativeValue(String key, Object value, long expiry) {
        memCachedClient.set(key, value, new Date(expiry * 1000));
    }

    @Override
    public void deleteNativeValue(String key) {
        memCachedClient.delete(key);
    }

    @Override
    public String getSystemName() {
        return MemCachedConfig.getConfig().getSystemName();
    }
}

到這一步爲止,底層的Flea緩存接口和實現已經完成,但目前還不能使用;服務器

3.4 定義Memcached鏈接池 --- MemCachedPool

/**
 * <p> MemCached鏈接池 </p>
 *
 * @author huazie
 */
public class MemCachedPool {

    private String poolName; // 鏈接池名

    private MemCachedConfig memCachedConfig; // MemCached 配置信息

    private SockIOPool sockIOPool; // MemCached SockIOPool

    private MemCachedPool() {
    }

    /**
     * <p> 獲取MemCached鏈接池實例 (默認) </p>
     *
     * @return MemCached鏈接池實例對象
     * @since 1.0.0
     */
    public static MemCachedPool getInstance() {
        MemCachedPool memCachedPool = new MemCachedPool();
        memCachedPool.memCachedConfig = MemCachedConfig.getConfig();
        memCachedPool.sockIOPool = SockIOPool.getInstance();
        return memCachedPool;
    }

    /**
     * <p> 獲取MemCached鏈接池實例(指定鏈接池名poolName) </p>
     *
     * @param poolName 鏈接池名
     * @return MemCached鏈接池實例對象
     * @since 1.0.0
     */
    public static MemCachedPool getInstance(String poolName) {
        MemCachedPool memCachedPool = new MemCachedPool();
        memCachedPool.poolName = poolName;
        memCachedPool.sockIOPool = SockIOPool.getInstance(poolName);
        return memCachedPool;
    }

    /**
     * <p> 初始化MemCached鏈接池 </p>
     */
    void initialize() {
        if (ObjectUtils.isEmpty(memCachedConfig)) {
            throw new RuntimeException("採用默認初始化,請使用MemCachedPool##getInstance()");
        }
        // ...省略 sockIOPool 初始化代碼
    }

    /**
     * <p> 初始化MemCached鏈接池 </p>
     *
     * @param cacheServerList 緩存服務器集
     * @param cacheParams     緩存參數集
     */
    void initialize(List<CacheServer> cacheServerList, CacheParams cacheParams) {
        if (StringUtils.isBlank(poolName)) {
            throw new RuntimeException("採用指定鏈接池名初始化,請使用MemCachedPool##getInstance(String poolName)");
        }
        // ...省略 sockIOPool 初始化代碼
    }

    // ...省略get方法
}

3.5 Memcached配置文件

flea-frame-cache 讀取 memcached.properties(Memcached配置文件),用做初始化MemCachedPoolapp

# Memcached配置
# Memcached緩存所屬系統名
memcached.systemName=FleaFrame
# Memcached服務器地址
memcached.server=127.0.0.1:31113,127.0.0.1:31114
# Memcached服務器權重分配
memcached.weight=1,1
# 初始化時對每一個服務器創建的鏈接數目
memcached.initConn=20
# 每一個服務器創建最小的鏈接數
memcached.minConn=20
# 每一個服務器創建最大的鏈接數
memcached.maxConn=500
# 自查線程週期進行工做,其每次休眠時間
memcached.maintSleep=60000
# Socket的參數,若是是true在寫數據時不緩衝,當即發送出去
memcached.nagle=true
# Socket阻塞讀取數據的超時時間
memcached.socketTO=3000
# Socket鏈接超時時間
memcached.socketConnectTO=3000
# Memcached分佈式hash算法
# 0 - native String.hashCode();
# 1 - original compatibility
# 2 - new CRC32 based
# 3 - MD5 Based
memcached.hashingAlg=3

3.6 定義抽象Flea緩存管理類 --- AbstractFleaCacheManager

/**
 * <p> 自定義抽象緩存管理類 </p>
 *
 * @author huazie
 */
public abstract class AbstractFleaCacheManager {

    private static final ConcurrentMap<String, AbstractFleaCache> cacheMap = new ConcurrentHashMap<>();

    private Map<String, Long> configMap = new HashMap<>();   // 各緩存的時間Map

    /**
     * <p> 獲取全部的Flea緩存 </p>
     *
     * @return 全部的Flea緩存
     */
    protected Collection<? extends AbstractFleaCache> loadCaches() {
        return cacheMap.values();
    }

    /**
     * <p> 根據指定緩存名獲取緩存對象 </p>
     *
     * @param name 緩存名
     * @return 緩存對象
     */
    public AbstractFleaCache getCache(String name) {
        if (!cacheMap.containsKey(name)) {
            synchronized (cacheMap) {
                if (!cacheMap.containsKey(name)) {
                    Long expiry = configMap.get(name);
                    if (ObjectUtils.isEmpty(expiry)) {
                        expiry = CommonConstants.NumeralConstants.ZERO; // 表示永久
                        configMap.put(name, expiry);
                    }
                    cacheMap.put(name, newCache(name, expiry));
                }
            }
        }
        return cacheMap.get(name);
    }

    /**
     * <p> 新建立一個緩存對象 </p>
     *
     * @param name   緩存名
     * @param expiry 失效時間(單位:秒  其中0:表示永久)
     * @return 新建的緩存對象
     */
    protected abstract AbstractFleaCache newCache(String name, long expiry);

    /**
     * <p> 設置各緩存失效時間配置Map </p>
     *
     * @param configMap 失效時間配置Map
     */
    public void setConfigMap(Map<String, Long> configMap) {
        this.configMap = configMap;
    }
}

3.7 定義Memcached Flea緩存管理類 MemCachedFleaCacheManager

上述 MemCachedFleaCache 使用, 須要初始化 MemCachedPoolsocket

/**
 * <p> MemCached Flea緩存管理類 </p>
 *
 * @author huazie
 */
public class MemCachedFleaCacheManager extends AbstractFleaCacheManager {

    private MemCachedClient memCachedClient;   // MemCached客戶端類

    /**
     * <p> 新建一個MemCached Flea緩存管理類 </p>
     */
    public MemCachedFleaCacheManager() {
        memCachedClient = new MemCachedClient();
        initPool();
    }

    /**
     * <p> 新建一個MemCached Flea緩存管理類 </p>
     *
     * @param memCachedClient MemCached客戶端
     */
    public MemCachedFleaCacheManager(MemCachedClient memCachedClient) {
        this.memCachedClient = memCachedClient;
        initPool();
    }

    /**
     * <p> 初始化MemCached鏈接池 </p>
     */
    private void initPool() {
        MemCachedPool.getInstance().initialize();
    }

    @Override
    protected AbstractFleaCache newCache(String name, long expiry) {
        return new MemCachedFleaCache(name, expiry, memCachedClient);
    }
}

好了,到了這一步,Memcached已接入完成,開始自測

3.8 Memcached接入自測 --- FleaCacheTest

首先,這裏須要按照 Memcached配置文件中的地址部署相應的 Memcached服務,可參考筆者的 這篇博文

下面開始演示咱們的Memcached接入自測:

@Test
    public void testMemeCachedFleaCache() {
        try {
            AbstractFleaCacheManager manager = FleaCacheManagerFactory.getFleaCacheManager(CacheEnum.MemCached.getName());
            AbstractFleaCache cache = manager.getCache("fleaparadetail");
            LOGGER.debug("Cache={}", cache);
            //#### 1.  簡單字符串
//            cache.put("menu1", "huazie");
//            cache.get("menu1");
            cache.delete("menu1");
//            cache.getCacheKey();
            LOGGER.debug(cache.getCacheName() + ">>>" + cache.getCacheDesc());
        } catch (Exception e) {
            LOGGER.error("Exception:", e);
        }
    }

4. 進階接入

4.1 定義抽象Spring緩存 --- AbstractSpringCache

該類與 AbstractFleaCache 不一樣之處在於,實現了 SpringCache 接口,用於對接 Spring,相關配置後面會介紹一下。

/**
 * <p> 抽象Spring緩存類,實現Spring的Cache 和 自定義的 IFleaCache接口 </p>
 *
 * @author huazie
 */
public abstract class AbstractSpringCache implements Cache, IFleaCache {

    private final String name;  // 緩存主要關鍵字(用於區分)

    private final IFleaCache fleaCache; // 具體Flea緩存實現

    public AbstractSpringCache(String name, IFleaCache fleaCache) {
        this.name = name;
        this.fleaCache = fleaCache;
    }

    @Override
    public String getName() {
        return name;
    }

    @Override
    public IFleaCache getNativeCache() {
        return fleaCache;
    }

    @Override
    public ValueWrapper get(Object key) {
        if (ObjectUtils.isEmpty(key))
            return null;
        ValueWrapper wrapper = null;
        Object cacheValue = get(key.toString());
        if (ObjectUtils.isNotEmpty(cacheValue)) {
            wrapper = new SimpleValueWrapper(cacheValue);
        }
        return wrapper;
    }

    @Override
    @SuppressWarnings(value = "unchecked")
    public <T> T get(Object key, Class<T> type) {
        if (ObjectUtils.isEmpty(key))
            return null;
        Object cacheValue = get(key.toString());
        if (ObjectUtils.isNotEmpty(type) && !type.isInstance(cacheValue)) {
            return null;
        }
        return (T) cacheValue;
    }

    @Override
    public <T> T get(Object key, Callable<T> valueLoader) {
        return null;
    }

    @Override
    public Object get(String key) {
        if (StringUtils.isBlank(key))
            return null;
        Object cacheValue = fleaCache.get(key);
        return cacheValue;
    }

    @Override
    public void put(Object key, Object value) {
        if (ObjectUtils.isEmpty(key))
            return;
        put(key.toString(), value);
    }

    @Override
    public ValueWrapper putIfAbsent(Object key, Object value) {
        if (ObjectUtils.isEmpty(key))
            return null;
        ValueWrapper wrapper = null;
        Object cacheValue = get(key.toString());
        if (ObjectUtils.isEmpty(cacheValue)) {
            put(key.toString(), value);
        } else {
            wrapper = new SimpleValueWrapper(cacheValue);
        }
        return wrapper;
    }

    @Override
    public void put(String key, Object value) {
        fleaCache.put(key, value);
    }

    @Override
    public void evict(Object key) {
        if (ObjectUtils.isEmpty(key))
            return;
        delete(key.toString());
    }

    @Override
    public void clear() {
        fleaCache.clear();
    }

    @Override
    public void delete(String key) {
        fleaCache.delete(key);
    }

    @Override
    public Set<String> getCacheKey() {
        return fleaCache.getCacheKey();
    }

    @Override
    public String getSystemName() {
        return fleaCache.getSystemName();
    }
}

4.2 定義Memcached Spring緩存 --- MemCachedSpringCache

MemCachedSpringCache 只定義構造方法,使用 MemCachedFleaCache 做爲具體緩存實現。

/**
 * <p> MemCached Spring Cache的實現(實現spring的Cache接口)</p>
 *
 * @author huazie
 */
public class MemCachedSpringCache extends AbstractSpringCache {

    /**
     * <p> 帶參數的構造方法,初始化MemCached Spring緩存類 </p>
     *
     * @param name      緩存主關鍵字
     * @param fleaCache 具體緩存實現
     */
    public MemCachedSpringCache(String name, IFleaCache fleaCache) {
        super(name, fleaCache);
    }

    /**
     * <p> 帶參數的構造方法,初始化MemCached Spring緩存類 </p>
     *
     * @param name            緩存主關鍵字
     * @param expiry          失效時長
     * @param memCachedClient MemCached客戶端
     */
    public MemCachedSpringCache(String name, long expiry, MemCachedClient memCachedClient) {
        this(name, new MemCachedFleaCache(name, expiry, memCachedClient));
    }
}

4.3 定義抽象Spring緩存管理類 --- AbstractSpringCacheManager

該類繼承 AbstractTransactionSupportingCacheManager,用於對接 Spring

/**
 * <p> 抽象Spring緩存管理類 </p>
 *
 * @author huazie
 */
public abstract class AbstractSpringCacheManager extends AbstractTransactionSupportingCacheManager {

    private static final ConcurrentMap<String, AbstractSpringCache> cacheMap = new ConcurrentHashMap<String, AbstractSpringCache>();

    private Map<String, Long> configMap = new HashMap<String, Long>();   // 各緩存的時間Map

    @Override
    protected Collection<? extends AbstractSpringCache> loadCaches() {
        return cacheMap.values();
    }

    @Override
    public AbstractSpringCache getCache(String name) {
        if(!cacheMap.containsKey(name)) {
            synchronized (cacheMap) {
                if (!cacheMap.containsKey(name)) {
                    Long expiry = configMap.get(name);
                    if (expiry == null) {
                        expiry = CommonConstants.NumeralConstants.ZERO; // 表示永久
                        configMap.put(name, expiry);
                    }
                    cacheMap.put(name, newCache(name, expiry));
                }
            }
        }
        return cacheMap.get(name);
    }

    /**
     * <p> 新建立一個緩存對象 </p>
     *
     * @param name   緩存名
     * @param expiry 失效時間(單位:秒  其中0:表示永久)
     * @return 新建的緩存對象
     */
    protected abstract AbstractSpringCache newCache(String name, long expiry);

    /**
     * <p> 設置各緩存失效時間配置Map </p>
     *
     * @param configMap 失效時間配置Map
     */
    public void setConfigMap(Map<String, Long> configMap) {
        this.configMap = configMap;
    }
}

4.4 定義Memcached Spring緩存管理類 --- MemCachedSpringCacheManager

該類基本實現同 MemCachedFleaCacheManager,不一樣在於newCache 方法返回一個 MemCachedSpringCache 的對象

/**
 * <p> Memcached的Spring緩存管理類 </p>
 *
 * @author huazie
 */
public class MemCachedSpringCacheManager extends AbstractSpringCacheManager {

    private MemCachedClient memCachedClient;   // Memcached客戶端類

    /**
     * <p> 新建一個MemCached Spring緩存管理類 </p>
     */
    public MemCachedSpringCacheManager() {
        memCachedClient = new MemCachedClient();
        initPool();
    }

    /**
     * <p> 新建一個MemCached Spring緩存管理類 </p>
     *
     * @param memCachedClient MemCached客戶端
     */
    public MemCachedSpringCacheManager(MemCachedClient memCachedClient) {
        this.memCachedClient = memCachedClient;
        initPool();
    }

    /**
     * <p> 初始化MemCached鏈接池 </p>
     */
    private void initPool() {
        MemCachedPool.getInstance().initialize();
    }

    @Override
    protected AbstractSpringCache newCache(String name, long expiry) {
        return new MemCachedSpringCache(name, expiry, memCachedClient);
    }
}

4.5 spring 配置

<!--
   配置緩存管理MemCachedSpringCacheManager
   配置緩存時間 configMap (key緩存對象名稱 value緩存過時時間)
-->
<bean id="memCachedSpringCacheManager" class="com.huazie.frame.cache.memcached.MemCachedSpringCacheManager">
    <property name="configMap">
        <map>
            <entry key="fleaparadetail" value="86400"/>
        </map>
    </property>
</bean>

 <!-- 開啓緩存, 此處定義表示由spring接入來管理緩存訪問 -->
 <cache:annotation-driven cache-manager="memCachedSpringCacheManager" proxy-target-class="true"/>

4.6 緩存自測

private ApplicationContext applicationContext;

    @Before
    public void init() {
        applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        LOGGER.debug("ApplicationContext={}", applicationContext);
    }

    @Test
    public void testMemCachedSpringCache() {
        try {
            AbstractSpringCacheManager manager = (MemCachedSpringCacheManager) applicationContext.getBean("memCachedSpringCacheManager");
            LOGGER.debug("MemCachedCacheManager={}", manager);

            AbstractSpringCache cache = manager.getCache("fleaparadetail");
            LOGGER.debug("Cache={}", cache);

            Set<String> cacheKey = cache.getCacheKey();
            LOGGER.debug("CacheKey = {}", cacheKey);
            // 緩存清理
//            cache.clear();

            //#### 1.  簡單字符串
//          cache.put("menu1", "huazie");
//            cache.get("menu1");
//            cache.get("menu1", String.class);

            //#### 2.  簡單對象(要是能夠序列化的對象)
//          String user = new String("huazie");
//          cache.put("user", user);
//          LOGGER.debug(cache.get("user", String.class));

            //#### 3.  List塞對象
//          List<String> userList = new ArrayList<String>();
//          userList.add("huazie");
//          userList.add("lgh");
//          cache.put("user_list", userList);

//          LOGGER.debug(cache.get("user_list",userList.getClass()).toString());

        } catch (Exception e) {
            LOGGER.error("Exception:", e);
        }
    }

4.7 業務邏輯層接入緩存管理

@Cacheable 使用,value 爲緩存名,也做緩存主關鍵字, key 爲具體的緩存鍵。

@Cacheable(value = "fleaparadetail", key = "#paraType + '_' + #paraCode")
public FleaParaDetail getParaDetail(String paraType, String paraCode) throws Exception {

    List<FleaParaDetail> fleaParaDetails = fleaParaDetailDao.getParaDetail(paraType, paraCode);
    FleaParaDetail fleaParaDetailValue = null;

    if (CollectionUtils.isNotEmpty(fleaParaDetails)) {
        fleaParaDetailValue = fleaParaDetails.get(0);
    }

    return fleaParaDetailValue;
}

結語

至此,Memcached 的接入工做已經所有完成,下一篇將講解 flea-frame-cache使用之Redis接入,敬請期待哦!!!