Aop+memcached缓存的实现
?
Aop+memcached缓存的实现
memcache的安装请参考:
http://www.linuxidc.com/Linux/2012-03/56500.htm
首先定义两个注解类,来说明是插入缓存还是删除缓存,这两个类可以在方法上来对你service需要进行缓存的方法进行注解标记,注解类内用key的前缀和缓存的有效时间,使用aop拦截service层含有这两个注解的方法
代码:
Cache注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface Cache{
? ?String prefix();//key的前缀
? ?long expiration()default 1000*60*60*2;//缓存有效期2小时
}
?
Flush注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface Flush{
? String prefix();//key的前缀
}
?
临时表用于存储key值:
表结构:
id --number(20) PRIMARY KEY
prefix--varchar(50)
cache_key--varchar(300)
add_time--datatime
?
memcache客户端代码,需要java_memcached-release_2.6.2.jar
?
public class Memcache{
?
? ? static MemCachedClient client=null;
? ? static{
? ? ? ? String [] servers={CacheConstent.SERVERS};
? ? ? ? SockIOPool pool=SockIOPool.getInstance();
? ? ? ? pool.serServers(servers); ??
? ? ? ? pool.setFailover(true);
? ? ? ? pool.setMinConn(5);//最小连接数
? ? ? ? pool.setMaxIdle(1000*60*60*6);//最大处理时间
? ? ? ? pool.setInitConn(20);//初始连接数
? ? ? ? pool.setMaxConn(250);//最大连接数
? ? ? ? pool.setMainSleep(30);//主线程的睡眠时间
?
? ? ? ? //设置TCP参数,连接超时等...
? ? ? ? pool.setNagle(false);
? ? ? ? pool.setSocketTO(3000);
? ? ? ? pool.setAliveCheck(true);
? ? ? ? pool.initialize();
? ? ? ? client=new MemCachedClient();
? ? ? ? client.setPrimitiveAsString(true);
? ? }
?
? ? public static Object get(String key){
? ? ? ? return client.get(key);
? ? }?
? ? public static boolean set(String key,Object obj){
? ? ? ? return client.set(key,obj);
? ? }
? ? public static boolean set(String key,Object obj,Date ExpireTime){
? ? ? ? return client.set(key,obj,ExpireTime);
? ? }
? ? public static boolean exists(String key){
? ? ? ? return client.keyExists(key);
? ? }
? ? public static boolean delete(String key){
? ? ? ? return client.delete(key);
? ? }
? ? public static Map<String ,Object>gets(String[] keys){
? ? ? ?return client.getMulti(keys);
? ? }
}
?
@Component
@Aspect
public class CacheAop{
? ?private ICacheLogService cacheLogService;
?
? ?@Resource(name="cacheLogService")
? ?public void setCacheLogService(ICacheLogService cacheLogService){
? ? ? this.cacheLogService=cacheLogService;
? ?}
? ?@Pointcut("execution(* com.test.service..*.*(..))")
? ?public void cachedPointcut(){
?
? ?}
? ?@Around("cachedPointcut()")
? ?public Object doAround(ProceedingJoinPoint call){
? ? ? Object result=null;
? ? ? Method[] methods=call.getTarget().getClass.getDeclaredMethods();
? ? ? Signature signature=call.getSignature();
? ? ? MethodSignature methodSignature=(MethodSignature)Signature;
? ? ? Method method=methodSignature.getMethod();
? ? ? for(Method m:methods){
? ? ? ? if(m.getName().equals(method.getName())){
? ? ? ? ? ?if(m.isAnnotationPresent(Cache.class)){
? ? ? ? ? ? ? Cache cache=m.getAnnotation(Cache.class);
? ? ? ? ? ? ? if(cache!=null){
? ? ? ? ? ? ? ? ?String tempKey=this.getKey(method,call.getArgs());
? ? ? ? ? ? ? ? ?String prefix=cache.prefix();
? ? ? ? ? ? ? ? ?String key=prefix+"_"+tempKey;
? ? ? ? ? ? ? ? ?result=Memcache.get(key);
? ? ? ? ? ? ? ? ?if(null==result){
? ? ? ? ? ? ? ? ? ? try{
? ? ? ? ? ? ? ? ? ? ? ?result=call.proceed();
? ? ? ? ? ? ? ? ? ? ? ?long expiration=cache.expiration();
? ? ? ? ? ? ? ? ? ? ? ?Date d=new Date();
? ? ? ? ? ? ? ? ? ? ? ?d=new Date(d.getTime()+expiration);
? ? ? ? ? ? ? ? ? ? ? ?Memcache.set(key,result,d);
? ? ? ? ? ? ? ? ? ? ? ?CacheLog log=new CacheLog();
? ? ? ? ? ? ? ? ? ? ? ?log.setPrefix(prefix);
? ? ? ? ? ? ? ? ? ? ? ?log.setCacheKey(key);
? ? ? ? ? ? ? ? ? ? }catch(Throewable e){
? ? ? ? ? ? ? ? ? ? ? ? e.printStackTrace();
? ? ? ? ? ? ? ? ? ? }
?
? ? ? ? ? ? ? ? ?}
? ? ? ? ? ? ? }
? ? ? ? ? ?}else if(method.isAnnotationPresent(Flush.class)){
? ? ? ? ? ? ? Flush flush=method.getAnnotaion(Flush.class);
? ? ? ? ? ? ? if(flush!=null){
? ? ? ? ? ? ? ? ?String prefix=flush.prefix();
? ? ? ? ? ? ? ? ?List<CacheLog>logs=cacheLogService.findListByPrefix(prefix);
? ? ? ? ? ? ? ? ?if(logs!=null && !logs.isEmpty()){
? ? ? ? ? ? ? ? ? ? int rows=cacheLogService.deleteByPrefix(prefix);
? ? ? ? ? ? ? ? ? ? if(rows>0){
? ? ? ? ? ? ? ? ? ? ? ?for(CacheLog log:logs){
? ? ? ? ? ? ? ? ? ? ? ? ? ?if(log!=nul){
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? String key=log.getCacheKey();
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Memcache.delete(key);?
? ? ? ? ? ? ? ? ? ? ? ? ? ?}
? ? ? ? ? ? ? ? ? ? ? ?} ? ? ? ? ? ? ? ? ? ? ? ??
?
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ?}
? ? ? ? ? ? ? } ? ? ? ? ??
?
? ? ? ? ? ?}else{
? ? ? ? ? ? ? ?try{
? ? ? ? ? ? ? ? ? ?result=call.proceed)();
? ? ? ? ? ? ? ?}catch(Throwable e){
? ? ? ? ? ? ? ? ?e.printStackTrace();
? ? ? ? ? ? ? ?}
? ? ? ? ? ?}
? ? ? ? ? ?break;
? ? ? ? }
?
? ? ? }
? ? ? return result;?
? ?}
?
? ?private String getKey(Method method , Objectp[]args){
? ? ? StringBuffer sb=new StringBuffer();
? ? ? String methodName=method.getName();
? ? ? sb.append(methodName);
? ? ? if(args!=null && args.length>0){
? ? ? ? ? for(Object arg:args){
? ? ? ? ? ? ?sb.append(arg);
? ? ? ? ? }
? ? ? }
? ? ? return sb.toString();
? ?}
?
}
?
service层方法添加注解:
@Cache(prefix=CacheConstant.ANLI,expiration=1000*60*60*10)
@TRansactional(propagation=Propagaton.NOT)SUPPORTED,readOnly=true)
public Object find(String id){
? ?......
}
?
?