这篇博文主要介绍如何使用SpringAOP + Redis +注解的方式实现缓存的开发。
org.springframework.data
spring-data-redis
1.6.1.RELEASE
redis.clients
jedis
2.7.3
#redis中心
#绑定的主机地址
redis.host=127.0.0.1
#指定Redis监听端口,默认端口为6379
redis.port=6379
#授权密码(本例子没有使用)
redis.password=
#最大空闲数:空闲链接数大于maxIdle时,将进行回收
redis.maxIdle=100
#最大连接数:能够同时建立的“最大链接个数”
redis.maxActive=300
#最大等待时间:单位ms
redis.maxWait=1000
#使用连接时,检测连接是否成功
redis.testOnBorrow=true
#当客户端闲置多长时间后关闭连接,如果指定为0,表示关闭该功能
redis.timeout=10000
/**
* 自定义注解,在插入、更新或者删除的时候更新对应的版本
* @author Chenth
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface PutCache {
String name() default "";
String value() default "";
}
(2)获取缓存版本GetCache.java
/**
* 自定义注解,对于查询使用缓存的方法加入该注解
* @author Chenth
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface GetCache {
String name() default "";
String value() default "";
}
@Aspect
public class GetCacheAOP {
private RedisTemplate redisTemplate;
ThreadLocal time=new ThreadLocal();
ThreadLocal tag=new ThreadLocal();
@Pointcut("@annotation(com.ninesky.classtao.springaop.annotation.GetCache)")
public void getCache(){
System.out.println("我是一个切入点");
}
/**
* 在所有标注@getCache的地方切入
* @param joinPoint
*/
@Before("getCache()")
public void beforeExec(JoinPoint joinPoint){
MethodSignature ms=(MethodSignature) joinPoint.getSignature();
Method method=ms.getMethod();
String ActionName = method.getAnnotation(GetCache.class).name();
String fieldList = method.getAnnotation(GetCache.class).value();
for (String field:fieldList.split(","))
{
if ("school_id".equals(field))
ActionName+="#"+ActionUtil.getSchoolID();
else if ("user_id".equals(field))
ActionName+="#"+ActionUtil.getUserID();
else if ("user_type".equals(field))
ActionName+="#"+ActionUtil.getUserType();
else ActionName+="#"+ActionUtil.getParameter(field);
}
ValueOperations operations =redisTemplate.opsForValue();
ActionUtil.setCache(true);
//如果是第一次取值.则将版本存放到redis数据库
if (operations.get(ActionName)==null) {
operations.increment(ActionName, 1);
return;
}
if (operations.get(ActionName).equals(ActionUtil.getParameter("cache_version")))
throw new CacheException("数据没有更新,可以采用本地数据!");
ActionUtil.setCache_version(operations.get(ActionName)+"");
}
public void setRedisTemplate(
RedisTemplate redisTemplate) {
this.redisTemplate = redisTemplate;
}
}
(2)、PutCache对应的切面
@Aspect
public class PutCacheAOP {
private RedisTemplate redisTemplate;
ThreadLocal time=new ThreadLocal();
ThreadLocal tag=new ThreadLocal();
@Pointcut("@annotation(com.ninesky.classtao.springaop.annotation.PutCache)")
public void PutCache(){
System.out.println("我是一个切入点");
}
/**
* 在所有标注@PutCache的地方切入
* @param joinPoint
*/
@After("PutCache()")
public void AfterExec(JoinPoint joinPoint){
MethodSignature ms=(MethodSignature) joinPoint.getSignature();
Method method=ms.getMethod();
String ActionName = method.getAnnotation(PutCache.class).name();
String fieldList = method.getAnnotation(PutCache.class).value();
for (String field:fieldList.split(","))
ActionName+="#"+ActionUtil.getParameter(field);
ValueOperations operations =redisTemplate.opsForValue();
operations.increment(ActionName, 1);
}
public void setRedisTemplate(
RedisTemplate redisTemplate) {
this.redisTemplate = redisTemplate;
}
}
/**
* 添加消息(校园风采、党建)
* @param request
*/
@PutCache(name="newsList",value="school_id,news_code")
@RequestMapping(value="/addNews")
public @ResponseBody Object addNews(HttpServletRequest request){
NewsVO vo = BeanUtil.formatToBean(NewsVO.class);
newsService.addNews(vo);
newsService.addInformation(vo);
return ResponseUtils.sendSuccess(vo);
}
/**
* 获取消息列表(Web)
* @param request
* @return
*/
@GetCache(name="newsList",value="school_id,news_code")
@RequestMapping(value="/getNewsListForWeb")
public @ResponseBody Object getNewsList(HttpServletRequest request){
NewsVO vo = BeanUtil.formatToBean(NewsVO.class);
if(IntegerUtil.isEmpty(vo.getSchool_id()))
vo.setSchool_id(ActionUtil.getSchoolID());
List list = newsService.getNewsList(vo);
return ResponseUtils.sendSuccess(list);
}