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){
......
}