运行环境:spring3.2.1 + simple-spring-memcached3.1.0(以下简称SSM)
1. 所需jar包,spring的包到spring官网下载,ssm所需包在这里下载,我下载的是3.1.0版本
注:解压simple-spring-memcached-3.1.0-dist.zip,复制lib目录中所有jar到工程lib中,如果有相同的jar,保留版本高的,删除版本低的。复制dist目录中除了带有test的之外所有jar到工程的lib中。最终lib包如下:
2. 配置项目的web.xml文件,因为本人项目用的是spring-mvc,所以代码如下:
<?xml version="1.0" encoding="UTF-8"?> <web-app version="3.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3.0.xsd" id="WebApp_ID" > <!-- ############################################################################## --> <!-- 字符集过滤器 --> <filter> <filter-name>characterEncodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> </filter> <filter-mapping> <filter-name>characterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- ############################################################################## --> <!-- spring-mvc 控制器 上下文Spring监听器 --> <display-name>Spring3MVC</display-name> <servlet> <servlet-name>spring</servlet-name> <servlet-class> org.springframework.web.servlet.DispatcherServlet </servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath*:spring-mvc.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>spring</servlet-name> <url-pattern>*.action</url-pattern> </servlet-mapping> <!-- 激活静态资源的默认配置,解决Rest风格兼容 <servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>*.css</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>*.js</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>*.gif</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>*.jpg</url-pattern> </servlet-mapping> --> <!-- ############################################################################## --> <!-- 欢迎页面 --> <welcome-file-list> <welcome-file>startLogin.action</welcome-file> </welcome-file-list> <!-- ############################################################################## --> <!-- tomcat多项目启动 --> <context-param> <param-name>webAppRootKey</param-name> <param-value>web.lxyy_spring.root</param-value> </context-param> <!-- ############################################################################## --> <!-- google的验证码插件 --> <servlet> <servlet-name>Kaptcha</servlet-name> <servlet-class>com.google.code.kaptcha.servlet.KaptchaServlet</servlet-class> <!-- 全都要数字 --> <init-param> <param-name>kaptcha.textproducer.char.string</param-name> <param-value>0123456789</param-value> </init-param> <!-- 去掉干扰线 --> <init-param> <param-name>kaptcha.noise.impl</param-name> <param-value>com.google.code.kaptcha.impl.NoNoise </param-value> </init-param> <init-param> <param-name>kaptcha.border</param-name> <param-value>no</param-value> </init-param> <init-param> <param-name>kaptcha.image.width</param-name> <param-value>65</param-value> </init-param> <init-param> <param-name>kaptcha.image.height</param-name> <param-value>30</param-value> </init-param> <init-param> <param-name>kaptcha.textproducer.char.length</param-name> <param-value>4</param-value> </init-param> <init-param> <param-name>kaptcha.textproducer.font.size</param-name> <param-value>25</param-value> </init-param> <init-param> <param-name>kaptcha.obscurificator.impl</param-name> <param-value>com.google.code.kaptcha.impl.ShadowGimpy</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>Kaptcha</servlet-name> <url-pattern>/kaptcha.jpg</url-pattern> </servlet-mapping> <!-- ############################################################################## --> <context-param> <param-name>log4jConfigLocation</param-name> <param-value>classpath:log4j.properties</param-value> </context-param> <context-param> <param-name>log4jRefreshInterval</param-name> <param-value>6000</param-value> </context-param> <!-- request监听 --> <listener> <listener-class>org.springframework.web.context.request.RequestContextListener </listener-class> </listener> </web-app>
3. spring配置文件如下
注:需要解压simple-spring-memcached-3.1.0.jar,找到simplesm-context.xml放到src目录下
<?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:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:cache="http://www.springframework.org/schema/cache" xmlns:jaxws="http://cxf.apache.org/jaxws" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache-3.2.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd"> <!-- 引入jdbc配置文件 --> <context:property-placeholder location="classpath*:jdbc.properties"/> <!--创建jdbc数据源 --> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"> <property name="driverClass" value="${driverClass}"/> <property name="jdbcUrl" value="${jdbcUrl}"/> <property name="user" value="${user}"/> <property name="password" value="${password}"/> <!--初始化时获取的连接数,取值应在minPoolSize与maxPoolSize之间。--> <property name="initialPoolSize" value="${initialPoolSize}"/> <!--连接池中保留的最小连接数。--> <property name="minPoolSize" value="${minPoolSize}"/> <!--连接池中保留的最大连接数。--> <property name="maxPoolSize" value="${maxPoolSize}"/> <!--最大空闲时间,60秒内未使用则连接被丢弃。若为0则永不丢弃。--> <property name="maxIdleTime" value="${maxIdleTime}"/> <!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。--> <property name="acquireIncrement" value="${acquireIncrement}"/> <!--每60秒检查所有连接池中的空闲连接。--> <property name="idleConnectionTestPeriod" value="${idleConnectionTestPeriod}"/> </bean> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource"/> </bean> <!-- (事务管理)transaction manager, use JtaTransactionManager for global tx --> <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <!-- 可通过注解控制事务 --> <tx:annotation-driven transaction-manager="transactionManager"/> <!-- 自动扫描bean,把作了注解的类转换为bean --> <context:component-scan base-package="com.dsideal" /> <!-- 加载组装所以配置文件 context:component-scan注册后可以省略当前配置 <context:annotation-config /> --> <!-- 通过注解,把URL映射到Controller上,该标签默认注册RequestMappingHandlerMapping和RequestMappingHandlerAdapter --> <mvc:annotation-driven /> <!-- 启动Spring MVC的注解功能,完成请求和注解POJO的映射 --> <!--Spring3.1开始的注解 HandlerMapping <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/> --> <!--Spring3.1开始的注解 HandlerAdapter <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/> --> <!-- 启用缓存注解 --> <cache:annotation-driven cache-manager="cacheManager"/> <bean id="cacheManager" class="org.springframework.cache.concurrent.ConcurrentMapCacheManager" /> <!-- 视图解析器 InternalResourceViewResolver:支持jsp和jstl解析器 --> <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <!-- 使用JSP页面进行输出 --> <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" /> <!-- 指定了表示层的前缀 --> <property name="prefix" value="/WEB-INF/bizroot/" /> <!-- 指定了表示层的后缀 --> <property name="suffix" value=".jsp" /> </bean> <!-- 处理文件上传处理 maxUploadSize:最大上传限制 uploadTempDir:上传临时路径,文件上传完成后,临时目录中的临时文件会被自动清楚 --> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver" p:defaultEncoding="UTF-8" p:maxUploadSize="5242880" p:uploadTempDir="upload/temp"> </bean> <!-- 拦截器 <mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/**"/> <bean class="com.dsideal.common.SysInteceptor"></bean> </mvc:interceptor> </mvc:interceptors> --> <!-- *********************** simple-spring-memcache ******************************* --> <!-- ssm 配置文件,主要用来加载组件核心的Advice,供程序调度使用;封装在 simple-spring-memcached-3.1.0.jar 文件中--> <import resource="simplesm-context.xml" /> <!-- 让代理机制起到作用,simple-spring-memcached主要是基于AOP的代理 --> <aop:aspectj-autoproxy /> <!-- com.google.code.ssm.CacheFactory是一个FactoryBean,会返回Cache(高速缓存)实体供Advice使用 --> <!-- FactoryBean解决的是如何创建无法直接通过new运算符创建的Bean,并注入到其他的bean中。也就是说FactoryBean是创建或者管理其他被注入和管理Bean的工厂Bean --> <bean name="defaultMemcachedClient" class="com.google.code.ssm.CacheFactory"> <property name="cacheClientFactory"> <!-- xmemcached配置方法 --> <bean name="cacheClientFactory" class="com.google.code.ssm.providers.xmemcached.MemcacheClientFactoryImpl" /> <!-- spymemcached配置方法 <bean name="cacheClientFactory" class="com.google.code.ssm.providers.spymemcached.MemcacheClientFactoryImpl" /> --> </property> <!-- 定义了缓存节点的IP地址和端口号 --> <property name="addressProvider"> <bean class="com.google.code.ssm.config.DefaultAddressProvider"> <property name="address" value="127.0.0.1:11211" /> </bean> </property> <!-- 定义了缓存节点的查找方法 --> <property name="configuration"> <bean class="com.google.code.ssm.providers.CacheConfiguration"> <property name="consistentHashing" value="true" /> </bean> </property> </bean> <!-- *********************** simple-spring-memcache ******************************* --> </beans>
4. Controller 类文件
package com.dsideal.sys.action; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; 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.RequestParam; import com.dsideal.sys.bean.SysLoginPersonBean; import com.dsideal.sys.service.ISysMemcachedTestService; @Controller public class SysLoginpersonController{ @Resource private ISysMemcachedTestService iSysMemcachedTestService; /** * <p>功能:登录</p> * @author 周枫 * @date 2013-3-7 * @param * @return void */ @RequestMapping(value="/login",method=RequestMethod.POST) public void login(HttpServletRequest request,HttpServletResponse response,@RequestParam("yzm") String yzm,SysLoginPersonBean loginPerson) { try { //save person_id to memcached //loginPerson.setPerson_id("8BEFBA28-627D-4A37-BAF9-E33FC0F44169"); //iSysMemcachedTestService.saveLoginPerson(loginPerson); //get person_id from memcached // SysLoginPersonBean lpBean = new SysLoginPersonBean(); // lpBean = iSysMemcachedTestService.getByPersonId("8BEFBA28-627D-4A37-BAF9-E33FC0F44169"); // System.out.print(lpBean.getLogin_name()); //delete person_id from memcached iSysMemcachedTestService.deletePerson("8BEFBA28-627D-4A37-BAF9-E33FC0F44169"); } catch (Exception e) { e.printStackTrace(); } } }
5. service文件:
package com.dsideal.sys.service; import com.dsideal.sys.bean.SysLoginPersonBean; import com.google.code.ssm.api.ParameterDataUpdateContent; import com.google.code.ssm.api.ParameterValueKeyProvider; public interface ISysMemcachedTestService { public void saveLoginPerson(SysLoginPersonBean lpBean); public SysLoginPersonBean getByPersonId(@ParameterValueKeyProvider String personId); public void updatePerson(@ParameterValueKeyProvider @ParameterDataUpdateContent SysLoginPersonBean lpBean); public void deletePerson(@ParameterValueKeyProvider String personId); }
6. serviceimpl文件:
解:组件所提供的切入点主要包括以下几种:
ReadThroughSingleCache、ReadThroughMultiCache、ReadThroughAssignCache
当遇到查询方法声明这些切入点时,组件首先会从缓存中读取数据,取到数据则跳过查询方法,直接返回。
取不到数据在执行查询方法,并将查询结果放入缓存,以便下一次获取。
InvalidateSingleCache、InvalidateMultiCache、InvalidateAssignCache
当遇到删除方法声明这些切入点时,组件会删除缓存中的对应实体
UpdateSingleCache、UpdateMultiCache、UpdateAssignCache
当遇到更新方法声明这些切入点是,组件会更新缓存中对应的实体,以便下次从缓存中读取出的数据状态是最新的
package com.dsideal.sys.service.impl; import java.util.HashMap; import java.util.Map; import org.apache.commons.collections.map.HashedMap; import org.springframework.stereotype.Service; import com.dsideal.sys.bean.SysLoginPersonBean; import com.dsideal.sys.service.ISysMemcachedTestService; import com.google.code.ssm.api.InvalidateSingleCache; import com.google.code.ssm.api.ParameterDataUpdateContent; import com.google.code.ssm.api.ParameterValueKeyProvider; import com.google.code.ssm.api.ReadThroughSingleCache; import com.google.code.ssm.api.UpdateSingleCache; @Service public class SysMemcachedTestServiceImpl implements ISysMemcachedTestService { private static final String NAMESPACE = "com.dsideal.sys.service.impl"; private Map<String,SysLoginPersonBean> person = new HashMap<String,SysLoginPersonBean>(); @Override public void saveLoginPerson(SysLoginPersonBean lpBean) { person.put(lpBean.getPerson_id(), lpBean); } /** * ReadThroughSingleCache、ReadThroughMultiCache、ReadThroughAssignCache 当遇到查询方法声明这些切入点时,组件首先会从缓存中读取数据,取到数据则跳过查询方法,直接返回。 取不到数据在执行查询方法,并将查询结果放入缓存,以便下一次获取 */ @Override @ReadThroughSingleCache(namespace = NAMESPACE, expiration = 600) public SysLoginPersonBean getByPersonId(@ParameterValueKeyProvider String personId) { System.out.println(personId); return person.get(personId); } @Override @UpdateSingleCache(namespace = NAMESPACE, expiration = 600) public void updatePerson(@ParameterValueKeyProvider @ParameterDataUpdateContent SysLoginPersonBean lpBean) { person.put(lpBean.getPerson_id(), lpBean); } @Override @InvalidateSingleCache(namespace = NAMESPACE) public void deletePerson(@ParameterValueKeyProvider String personId) { person.remove(personId); } }
7. bean类
注:这里bean一定要序列化,否则不能存入memcached
package com.dsideal.sys.bean; import java.io.Serializable; import com.google.code.ssm.api.CacheKeyMethod;
@SuppressWarnings("serial") public class SysLoginPersonBean implements Serializable{
private String person_id; private String login_name; private String login_pwd; private int b_use; private int identity_id; private int bureau_id; private String real_name; @CacheKeyMethod public String getPerson_id() { return person_id; } public void setPerson_id(String person_id) { this.person_id = person_id; } public String getLogin_name() { return login_name; } public void setLogin_name(String login_name) { this.login_name = login_name; } public String getLogin_pwd() { return login_pwd; } public void setLogin_pwd(String login_pwd) { this.login_pwd = login_pwd; } public int getB_use() { return b_use; } public void setB_use(int b_use) { this.b_use = b_use; } public int getIdentity_id() { return identity_id; } public void setIdentity_id(int identity_id) { this.identity_id = identity_id; } public int getBureau_id() { return bureau_id; } public void setBureau_id(int bureau_id) { this.bureau_id = bureau_id; } public String getReal_name() { return real_name; } public void setReal_name(String real_name) { this.real_name = real_name; } public SysLoginPersonBean() { } public SysLoginPersonBean(String person_id,String login_name,String login_pwd,int b_use,int identity_id,int bureau_id,String real_name) { this.person_id = person_id; this.login_name = login_name; this.login_pwd = login_pwd; this.b_use = b_use; this.identity_id = identity_id; this.bureau_id = bureau_id; this.real_name = real_name; } }
英文官方配置:http://code.google.com/p/simple-spring-memcached/wiki/Getting_Started
本人配置时主要借鉴的文章:http://blog.csdn.net/javaman_chen/article/details/7682290