首頁 > 軟體

Spring Cache整合Memcached

2020-06-16 17:33:38

使用memcahed的用戶端xmemcached實現Cache、CacheManager介面。

一、新增jar依賴


<dependency>
   <groupId>com.googlecode.xmemcached</groupId>
   <artifactId>xmemcached</artifactId>
   <version>2.0.0</version>
  </dependency>二、實現Cache介面

package org.springframework.cache.demo.memchache;

import Java.util.concurrent.TimeoutException;

import net.rubyeye.xmemcached.MemcachedClient;
import net.rubyeye.xmemcached.exception.MemcachedException;

import org.springframework.cache.Cache;
import org.springframework.cache.support.SimpleValueWrapper;

public class MemcachedCache1 implements Cache {
 
 private MemcachedClient memcachedClient;
 
 public MemcachedClient getMemcachedClient() {
  return memcachedClient;
 }
 public void setMemcachedClient(MemcachedClient memcachedClient) {
  this.memcachedClient = memcachedClient;
 }
 @Override
 public String getName() {
  return memcachedClient.getName();
 }
 @Override
 public Object getNativeCache() {
  return memcachedClient;
 }
 @Override
 public ValueWrapper get(Object key) {
  Object object = null;
  try {
   object = memcachedClient.get((String)key);
  } catch (TimeoutException e) {
   e.printStackTrace();
  } catch (InterruptedException e) {
   e.printStackTrace();
  } catch (MemcachedException e) {
   e.printStackTrace();
  }
  return (object != null ? new SimpleValueWrapper(object) : null);
 }
 
 @SuppressWarnings("unchecked")
 @Override
 public <T> T get(Object key, Class<T> type) {
  Object object = null;
  try {
   object = memcachedClient.get((String)key);
  } catch (TimeoutException e) {
   e.printStackTrace();
  } catch (InterruptedException e) {
   e.printStackTrace();
  } catch (MemcachedException e) {
   e.printStackTrace();
  }
  return (T)object;
 }
 @Override
 public void put(Object key, Object value) {
  try {
   memcachedClient.set((String) key, 86400, value);
  } catch (TimeoutException e) {
   e.printStackTrace();
  } catch (InterruptedException e) {
   e.printStackTrace();
  } catch (MemcachedException e) {
   e.printStackTrace();
  }
 
 }
 @Override
 public ValueWrapper putIfAbsent(Object key, Object value) {
  put(key, value);
  return new SimpleValueWrapper(value);
 }
 @Override
 public void evict(Object key) {
  try {
   memcachedClient.delete((String)key);
  } catch (TimeoutException e) {
   e.printStackTrace();
  } catch (InterruptedException e) {
   e.printStackTrace();
  } catch (MemcachedException e) {
   e.printStackTrace();
  } 
 }
 @Override
 public void clear() {
  try {
   memcachedClient.flushAll();
  } catch (TimeoutException e) {
   e.printStackTrace();
  } catch (InterruptedException e) {
   e.printStackTrace();
  } catch (MemcachedException e) {
   e.printStackTrace();
  }
 }
}
三、實現CacheManager


package org.springframework.cache.demo.memchache;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

import net.rubyeye.xmemcached.MemcachedClient;

import org.springframework.cache.Cache;
import org.springframework.cache.transaction.AbstractTransactionSupportingCacheManager;

public class MemcachedCacheManager extends AbstractTransactionSupportingCacheManager {
 private ConcurrentMap<String, Cache> cacheMap = new ConcurrentHashMap<String, Cache>();
 private Map<String, Integer> expireMap = new HashMap<String, Integer>(); // 快取的時間
 private MemcachedClient memcachedClient; // xmemcached的用戶端

 public MemcachedCacheManager() {
 }
 
 @Override
  protected Collection<? extends Cache> loadCaches() {
    Collection<Cache> values = cacheMap.values();
    return values;
  }

  @Override
  public Cache getCache(String name) {
    Cache cache = cacheMap.get(name);
    if (cache == null) {
      Integer expire = expireMap.get(name);
      if (expire == null) {
        expire = 0;
        expireMap.put(name, expire);
      }
      cache = new MemcachedCache(name, expire.intValue(), memcachedClient);
      cacheMap.put(name, cache);
    }
    return cache;
  }

  public void setMemcachedClient(MemcachedClient memcachedClient) {
    this.memcachedClient = memcachedClient;
  }

  public void setConfigMap(Map<String, Integer> configMap) {
    this.expireMap = configMap;
  }

}
四、spring設定


<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:cache="http://www.springframework.org/schema/cache"
 xmlns:p="http://www.springframework.org/schema/p"
 xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/cache
http://www.springframework.org/schema/cache/spring-cache.xsd">
 <!-- 啟用快取註解功能,這個是必須的,否則註解不會生效,另外,該註解一定要宣告在spring主組態檔中才會生效 -->
 <cache:annotation-driven cache-manager="cacheManager"/>

 <bean id="userService" class="org.springframework.cache.demo.UserService" />
 
  <!-- spring自己的換管理器,這裡定義了兩個快取位置名稱 ,既注解中的value --> 
    <bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager"> 
        <property name="caches"> 
            <set> 
                <bean class="org.springframework.cache.demo.memchache.MemcachedCache1"> 
                    <property name="memcachedClient" ref="memcachedClient" /> 
                </bean> 
            </set> 
        </property> 
    </bean>
   
 <!-- 設定memcached的快取伺服器 -->
 <bean id="memcachedClientBuilder" class="net.rubyeye.xmemcached.XMemcachedClientBuilder">
  <constructor-arg>
   <list>
    <bean class="java.net.InetSocketAddress">
     <constructor-arg value="192.168.1.90" />
     <constructor-arg value="11211" />
    </bean>
   </list>
  </constructor-arg>
  <property name="name" value="userCache"/>
 </bean>
 <bean id="memcachedClient" factory-bean="memcachedClientBuilder"
  factory-method="build" destroy-method="shutdown" />
 
</beans>另外一種實現方式,可以採用simple-spring-memcached實現,依賴jar包:


<dependency>
   <groupId>com.google.code.simple-spring-memcached</groupId>
   <artifactId>simple-spring-memcached</artifactId>
   <version>3.5.0</version>
  </dependency>
  <dependency>
   <groupId>com.google.code.simple-spring-memcached</groupId>
   <artifactId>xmemcached-provider</artifactId>
   <version>3.5.0</version>
  </dependency>基於xmemcached的spring整合。

也需要實現Cache介面:


package org.springframework.cache.demo.memchache;

import java.util.concurrent.TimeoutException;

import org.springframework.cache.Cache;
import org.springframework.cache.support.SimpleValueWrapper;

import com.google.code.ssm.api.format.SerializationType;
import com.google.code.ssm.providers.CacheException;

public class MemcachedCache2 implements Cache {

 private com.google.code.ssm.Cache cache;

 public com.google.code.ssm.Cache getCache() {
  return cache;
 }

 public void setCache(com.google.code.ssm.Cache cache) {
  this.cache = cache;
 }

 @Override
 public String getName() {
  return this.cache.getName();
 }

 @Override
 public Object getNativeCache() {
  return this.cache;
 }

 @Override
 public ValueWrapper get(Object key) {
    Object object = null; 
        try { 
            object = this.cache.get((String)key, SerializationType.JAVA); 
        } catch (TimeoutException e) { 
            e.printStackTrace(); 
        } catch (CacheException e) { 
            e.printStackTrace(); 
        } 
        return (object != null ? new SimpleValueWrapper(object) : null); 
 }

 @SuppressWarnings("unchecked")
 @Override
 public <T> T get(Object key, Class<T> type) {
  try {
   return (T)this.cache.get((String)key, SerializationType.JAVA);
  } catch (TimeoutException e) {
   e.printStackTrace();
  } catch (CacheException e) {
   e.printStackTrace();
  }
  return null;
 }

 @Override
 public void put(Object key, Object value) {
  try { 
            this.cache.set((String)key, 86400, value, SerializationType.JAVA); 
        } catch (TimeoutException e) { 
            e.printStackTrace(); 
        } catch (CacheException e) { 
            e.printStackTrace(); 
        } 
 }

 @Override
 public ValueWrapper putIfAbsent(Object key, Object value) {
  put(key, value);
  return new SimpleValueWrapper(value);
 }

 @Override
 public void evict(Object key) {
  try { 
            this.cache.delete((String)key); 
        } catch (TimeoutException e) { 
            e.printStackTrace(); 
        } catch (CacheException e) { 
            e.printStackTrace(); 
        } 
 }

 @Override
 public void clear() {
  try { 
            this.cache.flush(); 
        } catch (TimeoutException e) { 
            e.printStackTrace(); 
        } catch (CacheException e) { 
            e.printStackTrace(); 
        } 
 }
}
這裡就不實現CacheManager介面使用org.springframework.cache.support.SimpleCacheManager設定:


<?xml version='1.0' encoding='UTF-8'?>
<beans xmlns='http://www.springframework.org/schema/beans'
 xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
 xmlns:context='http://www.springframework.org/schema/context'
 xmlns:c='http://www.springframework.org/schema/c'
 xmlns:p='http://www.springframework.org/schema/p'
 xmlns:cache='http://www.springframework.org/schema/cache'
 xmlns:aop="http://www.springframework.org/schema/aop"
 xsi:schemaLocation='
  http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
        '>
       
 <!-- 啟用快取註解功能,這個是必須的,否則註解不會生效,另外,該註解一定要宣告在spring主組態檔中才會生效 -->
 <cache:annotation-driven cache-manager="cacheManager" />
 <bean id="userService" class="org.springframework.cache.demo.UserService" />

 <!-- spring自己的換管理器,這裡定義了兩個快取位置名稱 ,既注解中的value -->
 <bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager">
  <property name="caches">
   <set>
    <bean class="org.springframework.cache.demo.memchache.MemcachedCache2">
     <property name="cache" ref="memcachedCacheClient" />
    </bean>
   </set>
  </property>
 </bean>

 <!-- memcached client defaultCache -->
 <bean name="memcachedCacheClient" class="com.google.code.ssm.CacheFactory">
  <property name="cacheClientFactory">
   <bean
    class="com.google.code.ssm.providers.xmemcached.MemcacheClientFactoryImpl" />
  </property>
  <property name="addressProvider">
   <bean class="com.google.code.ssm.config.DefaultAddressProvider">
    <property name="address" value="192.168.1.90:11211" />
   </bean>
  </property>
  <property name="configuration">
   <bean class="com.google.code.ssm.providers.CacheConfiguration">
    <property name="consistentHashing" value="true" />
   </bean>
  </property>
  <property name="cacheName" value="userCache" />
 </bean>

</beans>

CentOS 6.6下Memcached 原始碼安裝設定  http://www.linuxidc.com/Linux/2015-09/123019.htm

Memcached 安裝及啟動指令碼 http://www.linuxidc.com/Linux/2013-07/87641.htm

PHP中使用Memcached的效能問題 http://www.linuxidc.com/Linux/2013-06/85883.htm

Ubuntu下安裝Memcached及命令解釋 http://www.linuxidc.com/Linux/2013-06/85832.htm

Memcached的安裝和應用 http://www.linuxidc.com/Linux/2013-08/89165.htm

使用Nginx+Memcached的小圖片儲存方案 http://www.linuxidc.com/Linux/2013-11/92390.htm

Memcached使用入門 http://www.linuxidc.com/Linux/2011-12/49516p2.htm


IT145.com E-mail:sddin#qq.com