目录

spring整合memcached

加入pom依赖

pom.xml
<dependency>
	<groupId>com.googlecode.xmemcached</groupId>
	<artifactId>xmemcached</artifactId>
	<version>2.0.0</version>
</dependency>

引入placeholder

application-context.xml
<!-- 配置文件位置 -->
<context:property-placeholder location="classpath:/memcached.properties" />

application-cache-memcached.xml

application-cache-memcached.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:p="http://www.springframework.org/schema/p"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:jpa="http://www.springframework.org/schema/data/jpa"
	xmlns:security="http://www.springframework.org/schema/security"
	xsi:schemaLocation="
		http://www.springframework.org/schema/beans 
		http://www.springframework.org/schema/beans/spring-beans-4.0.xsd">
 
	<!--xmemcached 配置-->
    <bean name="memcachedClient" class="net.rubyeye.xmemcached.utils.XMemcachedClientFactoryBean"
          destroy-method="shutdown">
        <property name="servers" value="${memcached.servers}"/>
        <!-- memcached集群权重配置 -->
        <!-- <property name="weights">
            <list>
                  <value>1</value>
                  <value>2</value>
                  <value>3</value>
            </list>
        </property> -->
        <property name="connectionPoolSize" value="${memcached.connectionPoolSize}"/>
        <property name="sessionLocator">
            <bean class="net.rubyeye.xmemcached.impl.KetamaMemcachedSessionLocator"/>
        </property>
        <property name="transcoder">
            <bean class="net.rubyeye.xmemcached.transcoders.SerializingTranscoder"/>
        </property>
        <property name="bufferAllocator">
            <bean class="net.rubyeye.xmemcached.buffer.SimpleBufferAllocator"/>
        </property>
        <property name="failureMode" value="true"/>
    </bean>
</beans>

memcached.properties

memcached.properties
# Memcached settings
#memcached服务器列表 host1:port1 host2:port2
memcached.servers=localhost:11211
#memcached 连接池大小
memcached.connectionPoolSize=30

MemcachedService.java

MemcachedService.java
package com.gxx.record.service;
 
/**
 * <dl>
 * <dt><b>Title:</b></dt>
 * <dd>
 * memcached服务接口</dd>
 * <dt><b>Description:</b></dt>
 * <dd>
 * <p>
 * none</dd>
 * </dl>
 *
 * @author Administrator
 * @version 1.0, 2015年7月23日
 * @since record
 *
 */
public interface MemcachedService {
	/**
     * 仅当存储空间中不存在键相同的数据时才保存
     * @param key
     * @param value
     */
    public <T> void addWithNoReply(String key, T value);
    /**
     * 设置键值对
     * @param key     key
     * @param expires 单位:秒,0 表示永不过期
     * @param value   必须是一个可序列化的对象, 可以是容器类型如:List,但容器里面保存的对象必须是可序列化的
     */
    public <T> void addWithNoReply(String key, int expires, T value);
    /**
     * 无论何时都保存
     * @param key
     * @param value
     */
    public <T> void set(String key, T value);
    /**
     * 设置键值对
     * @param key     key
     * @param expires 单位:秒,0 表示永不过期
     * @param value   必须是一个可序列化的对象, 可以是容器类型如:List,但容器里面保存的对象必须是可序列化的
     */
    public <T> void set(String key, int expires, T value);
    /**
     * 根据key获得值
     * @param key key
     * @return value
     */
    public <T> T get(String key);
}

MemcachedServiceImpl.java

MemcachedServiceImpl.java
package com.gxx.record.service.impl;
 
import net.rubyeye.xmemcached.MemcachedClient;
 
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
 
import com.gxx.record.service.MemcachedService;
 
/**
 * <dl>
 *    <dt><b>Title:</b></dt>
 *    <dd>
 *    	memcached服务实现类
 *    </dd>
 *    <dt><b>Description:</b></dt>
 *    <dd>
 *    	<p>none
 *    </dd>
 * </dl>
 *
 * @author Administrator
 * @version 1.0, 2015年7月23日
 * @since record
 *
 */
@Service("memcachedService")
public class MemcachedServiceImpl implements MemcachedService {
	/**
	 * 日志处理器
	 */
	private final Logger logger = Logger.getLogger(MemcachedServiceImpl.class);
    private int expires = 3600;//默认过期时间 单位秒 1个小时
    @Autowired
    private MemcachedClient memcachedClient;
 
    /**
     * 仅当存储空间中不存在键相同的数据时才保存
     * @param key
     * @param value
     */
    public <T> void addWithNoReply(String key, T value) {
        this.addWithNoReply(key, expires, value);
    }
 
    /**
     * 设置键值对
     * @param key     key
     * @param expires 单位:秒,0 表示永不过期
     * @param value   必须是一个可序列化的对象, 可以是容器类型如:List,但容器里面保存的对象必须是可序列化的
     */
    public <T> void addWithNoReply(String key, int expires, T value) {
        if (StringUtils.isEmpty(key)) return;
        try {
            if (memcachedClient != null) {
                memcachedClient.addWithNoReply(key, expires, value);
            }
        } catch(Exception e) {
            logger.error(e.getMessage(), e);
        }
    }
 
    /**
     * 无论何时都保存
     * @param key
     * @param value
     */
    public <T> void set(String key, T value) {
        this.set(key, expires, value);
    }
 
    /**
     * 设置键值对
     * @param key     key
     * @param expires 单位:秒,0 表示永不过期
     * @param value   必须是一个可序列化的对象, 可以是容器类型如:List,但容器里面保存的对象必须是可序列化的
     */
    public <T> void set(String key, int expires, T value) {
        if (StringUtils.isEmpty(key)) return;
        try {
            if (memcachedClient != null) {
                memcachedClient.set(key, expires, value);
            }
        } catch(Exception e) {
            logger.error(e.getMessage(), e);
        }
    }
 
    /**
     * 根据key获得值
     * @param key key
     * @return value
     */
    @SuppressWarnings("unchecked")
	public <T> T get(String key) {
        try {
            if (!StringUtils.isEmpty(key) && memcachedClient != null) {
                return (T)memcachedClient.get(key);
            }
        } catch(Exception e) {
            logger.error(e.getMessage(), e);
        }
        return null;
    }
}

MemcachedDto.java

MemcachedDto.java
package com.gxx.record.dto;
/**
 * <dl>
 *    <dt><b>Title:</b></dt>
 *    <dd>
 *    	用户传输对象
 *    </dd>
 *    <dt><b>Description:</b></dt>
 *    <dd>
 *    	<p>none
 *    </dd>
 * </dl>
 *
 * @author Administrator
 * @version 1.0, 2015年6月18日
 * @since record
 *
 */
public class MemcachedDto extends BaseDto {
    private String key;//键
    private String value;//值
	public String getKey() {
		return key;
	}
	public void setKey(String key) {
		this.key = key;
	}
	public String getValue() {
		return value;
	}
	public void setValue(String value) {
		this.value = value;
	}
}

MemcachedController.java

MemcachedController.java
package com.gxx.record.web.memcached;
 
import javax.servlet.http.HttpServletRequest;
 
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
 
import com.gxx.record.dto.MemcachedDto;
import com.gxx.record.service.MemcachedService;
 
/**
 * MemcachedController
 * 
 * @author gxx
 */
@Controller
@RequestMapping("/memcached/")
public class MemcachedController {
	/**
	 * 日志处理器
	 */
	private final Logger logger = Logger.getLogger(MemcachedController.class);
 
	@Autowired
	private MemcachedService memcachedService;
 
	@RequestMapping(value = "/preMemcachedFtl", method = RequestMethod.GET)
	public String preMemcachedFtl() {
		return "memcached/preMemcachedFtl";
	}
 
	/**
	 * 设置
	 * @param request
	 * @param memcachedDto
	 * @return
	 */
	@RequestMapping(value = "/set",produces="application/json")
	public @ResponseBody MemcachedDto set(HttpServletRequest request, MemcachedDto memcachedDto) {
		logger.info("设置:键=[" + memcachedDto.getKey() + "],值=[" + memcachedDto.getValue() + "]");
		/**
		 * 1.设置值
		 */
		memcachedService.set(memcachedDto.getKey(), memcachedDto.getValue());
		/**
		 * 2.返回结果
		 */
		memcachedDto.setSuccess(true);
		memcachedDto.setMessage("设置成功!");
		return memcachedDto;
	}
 
	/**
	 * 获取值
	 * @param request
	 * @param memcachedDto
	 * @return
	 */
	@RequestMapping(value = "/get",produces="application/json")
	public @ResponseBody MemcachedDto get(HttpServletRequest request, MemcachedDto memcachedDto) {
		logger.info("获取值:键=[" + memcachedDto.getKey() + "]");
		/**
		 * 1.获取值
		 */
		String obj = (String)memcachedService.get(memcachedDto.getKey());
		/**
		 * 2.返回结果
		 */
		memcachedDto.setSuccess(true);
		memcachedDto.setMessage("获取成功");
		memcachedDto.setValue(obj);
		return memcachedDto;
	}
}

preMemcachedFtl.ftl

preMemcachedFtl.ftl
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
		<title>memcached页面</title>
	</head>
	<body>
		<form action="/record/memcached/set.htm" method="post">
			<table border="1">
				<tr><td>键:</td><td><input type="text" name="key"/></td></tr>
				<tr><td>值:</td><td><input type="text" name="value"/></td></tr>
				<tr><td colspan="2" align="center"><input type="submit" value="设置"/></td></tr>
			</table>
		</form>
		<form action="/record/memcached/get.htm" method="post">
			<table border="1">
				<tr><td>键:</td><td><input type="text" name="key"/></td></tr>
				<tr><td colspan="2" align="center"><input type="submit" value="获取"/></td></tr>
			</table>
		</form>
	</body>
</html>

演示

gxx@iZ23goxo66aZ:~$ telnet localhost 11211 #连接memcached
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
get name #获得name
VALUE name 0 9
关向辉 #已经设置的值
END
quit #退出
Connection closed by foreign host.
gxx@iZ23goxo66aZ:~$