SpringBoot 集成 Redis 实现缓存处理(Spring AOP实现)

  • 引入依赖

        <!--引入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();
    }

}

也可以利用 redis 管理 mybatis 的二级缓存实现 使用redis管理Mybatis的二级缓存

发布了118 篇原创文章 · 获赞 20 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/zhang33565417/article/details/100154406