java使用redis缓存可以使用jedis框架,jedis操作简单,没有什么复杂的东西需要学习,网上资料很多,随便看看就会了.
将spring与redis缓存集成,其实也是使用jedis框架,只不过spring对它进行了一层封装,并将这层封装库命名为spring-data-redis.
下面将要使用spring-data-redis与jedis的jar包,并通过spring的aop功能,将redis缓存无缝无侵入的整合进来.
1.先下载好依赖包
org.springframework
spring-core
4.1.1.RELEASE
org.springframework.data
spring-data-redis
1.4.1.RELEASE
redis.clients
jedis
2.6.0
3.1 声明两个注解类,用于定义哪些方法将使用缓存
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface Cacheable {
public enum KeyMode{
DEFAULT, //只有加了@CacheKey的参数,才加入key后缀中
BASIC, //只有基本类型参数,才加入key后缀中,如:String,Integer,Long,Short,Boolean
ALL; //所有参数都加入key后缀
}
public String key() default ""; //缓存key
public KeyMode keyMode() default KeyMode.DEFAULT; //key的后缀模式
public int expire() default 0; //缓存多少秒,默认无限期
}
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.PARAMETER})
public @interface CacheKey {}
3.2 创建一个Aop拦截器的处理类,用于拦截加了@Cacheable的方法
@Aspect
@Component
public class CacheableAop {
@Autowired private RedisTemplate redisTemplate;
@Around("@annotation(cache)")
public Object cached(final ProceedingJoinPoint pjp,Cacheable cache) throws Throwable {
String key=getCacheKey(pjp, cache);
ValueOperations valueOper=redisTemplate.opsForValue();
Object value=valueOper.get(key); //从缓存获取数据
if(value!=null) return value; //如果有数据,则直接返回
value = pjp.proceed(); //跳过缓存,到后端查询数据
if(cache.expire()<=0) { //如果没有设置过期时间,则无限期缓存
valueOper.set(key, value);
} else { //否则设置缓存时间
valueOper.set(key, value,cache.expire(),TimeUnit.SECONDS);
}
return value;
}
/**
* 获取缓存的key值
* @param pjp
* @param cache
* @return
*/
private String getCacheKey(ProceedingJoinPoint pjp,Cacheable cache) {
StringBuilder buf=new StringBuilder();
buf.append(pjp.getSignature().getDeclaringTypeName()).append(".").append(pjp.getSignature().getName());
if(cache.key().length()>0) {
buf.append(".").append(cache.key());
}
Object[] args=pjp.getArgs();
if(cache.keyMode()==KeyMode.DEFAULT) {
Annotation[][] pas=((MethodSignature)pjp.getSignature()).getMethod().getParameterAnnotations();
for(int i=0;i
4.使用缓存示例
@Service
@Transactional
public class DemoServiceImpl implements DemoService {
@Autowired private DemoDao demoDao;
public List findAll() {
return demoDao.findAll();
}
/*
对get()方法配置使用缓存,缓存有效期为3600秒,缓存的key格式为:{package_name}.DemoServiceImpl.get
同时为参数配置了@CacheKey后,表示此参数的值将做为key的后缀,此例的key,最终是:{package_name}.DemoServiceImpl.get.{id}
可以为多个参数配置@CacheKey,拦截器会调用参数的toString()做为key的后缀
若配置多个@CacheKey参数,那么最终的key格式为:{package_name}.{class_name}.{method}.{arg1}.{arg2}.{...}
*/
@Cacheable(expire=3600)
public Demo get(@CacheKey String id) {
return demoDao.get(id);
}
public Demo getByName(String name) {
return demoDao.getByName(name);
}
}
这只是一个初步整合方案,测试可行,还未在生产中使用,实际效果待验正.