spring boot 十八 redis (AOP 方式)

本文详细介绍了如何在Spring Boot项目中利用AOP和Redis进行方法级别的缓存实现。通过自定义注解和AOP切面,实现了方法调用前后的缓存读写逻辑,有效减轻了数据库负担,提高了应用性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在上一章的基础上 。升级代码。

第一步加入 AOP

       <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>```

第二步 编写注解方法

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
@Documented
public @interface MyRedis {

    String value() ;

    long expire() default -1;
    
}

第三步,编写AOP 处理方法

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

@Aspect
@Component
public class RedisHandle {

    @Autowired
    RedisTemplate redisTemplate;

    @Around("@annotation(myRedis)")
    public Object aroundMethod(ProceedingJoinPoint pjd, MyRedis myRedis) throws Throwable {

        Object[] args = pjd.getArgs();
        String key = myRedis.value();

        for (int i = 0; i < args.length; i++) {
            String replace = "#{" + i + "}";
            key = key.replace(replace, String.valueOf(args[i]));
        }

        ValueOperations valueOperations = redisTemplate.opsForValue();
        Object value = valueOperations.get(key);
        //redis 热点问题
        //服务器多线程并发访问时,可能会有多个线程同时访问为空,都会去执行设置操作,
        if (value == null) {
            //可能有多个线程阻塞在这里,当synchronized执行完成之后。
            synchronized (this){
                value = valueOperations.get(key);
                //每个线程进入后,发现如果已经有值了,就不再执行set操作
                if(value==null){
                    value = pjd.proceed();
                    valueOperations.set(key, value, myRedis.expire(), TimeUnit.SECONDS);
                }
            }
       }
        return value;
    }
}
    @MyRedis(value = "userkey#{0}", expire = 60 * 60 * 6)
    public User getUser(Long id) {
        ... 业务代码....
        return user;
    }
    
    @Override
    //这里的 value  是用于 redis 的可以 组拼方式
    //{1} 代表第二个参数来拼  {0} 就是第一个参数 举例如下:
    //  userKey#{1}   == userKey + name
    //  userKey#{0}   == userKey + id
    @MyRedis(value = "userKey#{1}", expire = 10)
    public User getUser(String id, String name) {
        System.out.println("读取数据库");
        return userDao.getUser(id);
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值