一、序言
有了缓存,还是喜欢用注解去使用,本想和spring 写一个类似ehcache 的东西,后来发google 已经提供了spring 和memcache 的 注解配置,那就先拿来用用了~。~。
二、基本配置:
2.1 先把spring 和 memcached 结合起来,创建一个spring-xmemcached.xml 的文件
<!-- 用这个代替xmemcacheClient去构建client --> <bean id="xmemcacheBuilder" class="net.rubyeye.xmemcached.XMemcachedClientBuilder"> <!-- 暂时我们就用两个端口 --> <constructor-arg> <list> <bean class="java.net.InetSocketAddress"> <constructor-arg> <value>localhost</value> </constructor-arg> <constructor-arg> <value>11211</value> </constructor-arg> </bean> <bean class="java.net.InetSocketAddress"> <constructor-arg> <value>localhost</value> </constructor-arg> <constructor-arg> <value>11212</value> </constructor-arg> </bean> </list> </constructor-arg> <!-- 权重配置 --> <constructor-arg> <list> <value>1</value> <value>2</value> </list> </constructor-arg> <!--</property>--> <!-- nio 连接池 配置,默认是 1 --> <property name="connectionPoolSize" value="2"/> <!-- 二进制协议 ,默认是 TextCommandFactory--> <property name="commandFactory"> <bean class="net.rubyeye.xmemcached.command.BinaryCommandFactory"/> </property> <!--分布式策略 一致性hash,默认是 ArrayMemcachedSessionLocator --> <property name="sessionLocator"> <bean class="net.rubyeye.xmemcached.impl.KetamaMemcachedSessionLocator"/> </property> <!--序列化转换器,默认就是这个 --> <!--<property name="transcoder" value="net.rubyeye.xmemcached.transcoders.SerializingTranscoder"/>--> <!--字节缓冲器,不知道为啥这玩意儿过时了,源码默认采用的这个!! --> <!--<property name="bufferAllocator" value="net.rubyeye.xmemcached.buffer.SimpleBufferAllocator"/>--> </bean> <!-- 配置一个客户端 --> <bean name="xmemcachedClient" factory-bean="xmemcacheBuilder" factory-method="build" destroy-method="shutdown"/>
测试一下:可以操作就表示 基本配置成功了
ApplicationContext context = new ClassPathXmlApplicationContext("spring/spring-xmemcached.xml"); MemcachedClient client = (MemcachedClient) context.getBean("xmemcachedClient"); System.out.println(client); client.add("name",100,"张三"); System.out.println(client.get("name")); client.delete("name"); System.out.println(client.get("name"));
还是可以参考 https://code.google.com/p/xmemcached/wiki/User_Guide_zh
三、spring+memcached 注解的试用
3.1 引入依赖:
<dependency> <groupId> com.google.code.simple-spring-memcached </groupId> <artifactId> xmemcached-provider </artifactId> <version>3.5.0</version> </dependency>
3.2 基本配置:
<!-- 轻轻的扫描一下 --> <context:component-scan base-package="com.raycloud.plugin.memcache"/> <!-- AOP 你懂的 --> <aop:aspectj-autoproxy /> <!-- simple-spring-memcached 目录下的 --> <import resource="classpath:simplesm-context.xml" /> <!-- 默认一个client --> <bean name="defaultMemcachedClient" class="com.google.code.ssm.CacheFactory"> <property name="cacheClientFactory"> <bean name="cacheClientFactory" class="com.google.code.ssm.providers.xmemcached.MemcacheClientFactoryImpl" /> </property> <property name="addressProvider"> <bean class="com.google.code.ssm.config.DefaultAddressProvider"> <property name="address" value="127.0.0.1:11211,127.0.0.1:11212" /> </bean> </property> <!-- 一致性hash ~。~ --> <property name="configuration"> <bean class="com.google.code.ssm.providers.CacheConfiguration"> <property name="consistentHashing" value="true" /> </bean> </property> </bean> <!-- 这玩意儿在3.2 后,文档可以指定顺序 以及 拦截器 前后执行 - -!暂时没用过,加上不报错 --> <bean class="com.google.code.ssm.Settings"> <property name="order" value="500" /> </bean>
3.3 测试一下:我们建立TestDao 和 Test 类,记得在扫描的package 下哦!
import com.google.code.ssm.api.ParameterValueKeyProvider; import com.google.code.ssm.api.ReadThroughSingleCache; import org.springframework.stereotype.Component; /** * Created by qiqiang on 2014/12/22. */ @Component public class TestDao { @ReadThroughSingleCache(namespace = "test", expiration = 30000) public long getUserById(@ParameterValueKeyProvider long id) throws Exception{ System.out.println("没有缓存命中"); return id; } }
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations="classpath:spring/spring-xmemcached.xml") public class Test { @Autowired private TestDao testDao; @org.junit.Test public void x(){ try { System.out.println( testDao.getUserById(2l)+"------------------------"); }catch (Exception e){ e.printStackTrace(); } } }
忘记了,还得加测试的依赖:
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>3.2.4.RELEASE</version> <scope>test</scope> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency>
3.4 OK 就测试完成了,当然你也可以用spring 定义的缓存接口,和 ehcache 类似的啦,看配置:
为了配套依赖:
<dependency> <groupId> com.google.code.simple-spring-memcached </groupId> <artifactId>spring-cache</artifactId> <version>3.5.0</version> </dependency>
<cache:annotation-driven /> <!-- 这里的cacheManager 缓存名字是默认的,要改,就参考我spring+ehcache 的配置改 --> <bean name="cacheManager" class="com.google.code.ssm.spring.SSMCacheManager"> <property name="caches"> <set> <bean class="com.google.code.ssm.spring.SSMCache"> <constructor-arg name="cache" index="0" ref="defaultCache" /> <!-- 默认 5 minutes --> <constructor-arg name="expiration" index="1" value="300" /> <!-- @CacheEvict(..., "allEntries" = true) won't work because allowClear is false, so we won't flush accidentally all entries from memcached instance --> <!-- 这里表示我们不会全部清除所有缓存,使用ehcache 的时候我们就会发现, @CacheEvict(..., "allEntries" = true) 它是按 配置的缓存名 就行清除的,而memcached 我们是通过namespace 进行清除的,还有指定时间,这是我最喜欢的了~。~ --> <constructor-arg name="allowClear" index="2" value="false" /> </bean> </set> </property> </bean> <bean name="defaultCache" class="com.google.code.ssm.CacheFactory"> <property name="cacheName" value="defaultCache"/> <property name="cacheClientFactory"> <bean name="cacheClientFactory" class="com.google.code.ssm.providers.xmemcached.MemcacheClientFactoryImpl"/> </property> <property name="addressProvider"> <bean class="com.google.code.ssm.config.DefaultAddressProvider"> <property name="address" value="127.0.0.1:11211,127.0.0.1:11212"/> </bean> </property> <property name="configuration"> <bean class="com.google.code.ssm.providers.CacheConfiguration"> <property name="consistentHashing" value="true"/> </bean> </property> </bean>
3.5 现在来看看 这种方式得测试,应该比较熟悉~。~!
TestDao2 和上面液氧,就改了下名字
@Component public class TestDao2 { @CachePut(value = "defaultCache",key="#id") public long getUserById(long id) throws Exception{ System.out.println("没有缓存命中"); return id; } @Cacheable(value = "defaultCache") public String getList(String author) throws Exception { System.out.println("没有缓存命中"); return author; } }
Test,和上面一样
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations="classpath:spring/spring-xmemcached.xml") public class Test { @Autowired private TestDao2 testDao2; @org.junit.Test public void x(){ try { System.out.println( testDao2.getUserById(2l)+"------------------------"); }catch (Exception e){ e.printStackTrace(); } } }
同样可以实现缓存
小结:
1.这里介绍了spring +xmemcached 配置,以及注解的配置,关于注解的一些详细资料下次介绍
2.由于有namespace 和 时间的控制,使用起来非常方便,集群部署,容错 都比较舒服的~。~,有错误请指出!
3.上面的来源 大部分还是文档介绍,当翻译下而已,更多的大家可以参考下面资料!
源码
https://github.com/ragnor/simple-spring-memcached
文档
https://code.google.com/p/simple-spring-memcached/wiki/Getting_Started
https://code.google.com/p/simple-spring-memcached/wiki/UserGuide
https://code.google.com/p/xmemcached/wiki/User_Guide_zh
别人的例子
http://weblog4j.com/2013/05/31/simple-spring-memcached-spring-caching-abstraction-and-memcached/