-
引入依赖
<!--引入jedis-->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.8.2</version>
</dependency>
-
编写一个元注解类 RedisCache,被该注解定义的类都自动实现AOP缓存处理
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
//注解生效的位置
@Target(ElementType.METHOD)
//注解生效的时机 运行时生效
@Retention(RetentionPolicy.RUNTIME)
public @interface RedisCache {
}
-
redis 的配置类 RedisConf
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import redis.clients.jedis.Jedis;
@Configuration
public class RedisConf {
@Bean
public Jedis getJedis(){
Jedis jedis = new Jedis("192.168.174.888", 6379);
return jedis;
}
}
-
Spring AOP实现监控所有被@RedisCache注解的方法缓存
@Configuration
@Aspect
public class RedisCommonCache {
@Autowired
private Jedis jedis;
private static Logger logger = LoggerFactory.getLogger(RedisCommonCache.class);
/**
* 环绕处理,先从Redis里获取缓存,查询不到,就查询MySQL数据库,
* 然后再保存到Redis缓存里
* @return
*/
//只切有这个自定义注解的方法
@Around("@annotation(com.baizhi.annotation.RedisCache)")
public Object around(ProceedingJoinPoint proceedingJoinPoint)throws Throwable{
long startTime = System.currentTimeMillis();
//获得目标方法的方法名称
MethodSignature signature = (MethodSignature) proceedingJoinPoint.getSignature();
String methodName = signature.getName();
logger.info("方法名:"+methodName);
//获得目标方法所在类
String className = proceedingJoinPoint.getTarget().getClass().getName();
logger.info("类名:"+className);
StringBuilder builder = new StringBuilder();
builder.append(methodName).append(":");
//获取目标方法的参数
Object[] args = proceedingJoinPoint.getArgs();
//拼接valueKey
for (int i = 0; i < args.length; i++) {
Object arg = args[i];
builder.append(arg);
if (i == args.length-1){
break;
}
builder.append(":");
}
String valueKey = builder.toString();
//判断当前这个方法在缓存中是否存在
//存在 直接从缓存中取数据 用fastjson反序列化
Object result = null;
if(jedis.hexists(className,valueKey)){
logger.info("**********从Redis中查到了数据**********");
logger.info("Redis的KEY值:"+className);
logger.info("REDIS的VALUEKEY值:"+valueKey);
String s = jedis.hget(className, valueKey);
result =JSONObject.parse(s);
logger.info("命中时处理查询所用时间:"+(System.currentTimeMillis()-startTime));
}else {
//不存在 放行 去数据库中查并存入 redis 中
logger.info("**********没有从Redis查到数据**********");
logger.info("**********开始从MySQL查询数据**********");
//这里注意 一定要有返回值,否则会出现空指针
result = proceedingJoinPoint.proceed();
logger.info("未命中时处理查询所用时间:"+(System.currentTimeMillis()-startTime));
jedis.hset(className,valueKey,JSONObject.toJSONStringWithDateFormat(result,"yyyy-MM-dd HH:mm:ss"));
logger.info("Redis的KEY值:"+className);
logger.info("REDIS的VALUEKEY值:"+valueKey);
logger.info("**********数据成功保存到Redis缓存!!!**********");
}
jedis.close();
return result;
}
//增删改操作会先将对应的缓存从redis中删除,再重新查询数据库并重新存入redis缓存
@After("execution(* com.baizhi.service.*.*(..)) && !execution(* com.xxxx.service.*.select*(..))&& !execution(* com.xxxx.service.*.find*(..))")
public void after(JoinPoint joinPoint){
String name = joinPoint.getTarget().getClass().getName();
jedis.del(name);
jedis.close();
}
}