AOP實現redis緩存


AOP實現redis緩存

redis使用AOP實現記錄緩存, 可以大大減少代碼量, 提高工作效率

1. 配置redis

1.1配置文件

創建一個redis.properties

# 配置單台redis
redis.host=192.168.126.129
redis.port=6379

1.2編輯配置類

@Configuration  //標識我是配置類
@PropertySource("classpath:/properties/redis.properties") // 讀取配置文件
public class RedisConfig {

    @Value("${redis.host}")
    private String  host;
    @Value("${redis.port}")
    private Integer port;

    @Bean
    public Jedis jedis(){
        //數據寫死?????????
        return new Jedis(host,port);
    }
}

2. 自定義注解

在指定的方法上使用, 把方法執行的結果使用AOP自動解析為json並存入redis 緩存

@Target(ElementType.METHOD)         //注解在方法中使用
@Retention(RetentionPolicy.RUNTIME) //運行期有效
public @interface CacheFind {

    String key();              //1.設定key 用戶自己設定
    int seconds() default  0;  //2.可以指定超時時間,也可以不指定.

}

3. AOP實現redis緩存

@Component  //1.我是一個javaBean
@Aspect     //2.我是一個切面
public class CacheAOP {

    //引入redis緩存配置
    @Autowired
    private Jedis jedis;


    /**
     * AOP緩存實現的業務策略
     * 1.切入點表達式應該攔截  @CacheFind注解
     * 2.通知方法: 環繞通知
     * 注意事項:  如果使用環繞通知,則必須在第一個參數的位置添加 ProceedingJoinPoint
     *
     * 動態獲取注解參數的步驟:
     *  1.@annotation(cacheFind)   切入點表達式要求攔截一個類型為cacheFind注解.
     *  2.並且利用連接點為參數中的cacheFind賦值.
     * */

    @Around("@annotation(cacheFind)")
    public Object around(ProceedingJoinPoint joinPoint, CacheFind cacheFind){
        try {
            // 目標方法執行的返回結果
            Object result = null;
            //1.如何動態獲取注解中的數據
            String prekey = cacheFind.key();
            //2.動態獲取方法中的參數  將數組轉化為字符串
            String args = Arrays.toString(joinPoint.getArgs());
            String key = prekey + "::" + args;
            //3.檢驗redis中是否有數據
            if(jedis.exists(key)){
                //有緩存  從redis緩存中獲取json 之后還原對象返回
                String json = jedis.get(key);
                //target代表這目標方法的返回值類型......
                //動態獲取目標方法的返回值類型??   向上造型 不用強轉   向下造型
                MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
               Class returnClass = methodSignature.getReturnType();
                //將json數據轉化為對象
                result = ObjectMapperUtil.toObject(json, returnClass);
                System.out.println("AOP實現緩存查詢!!!!");

            }else{
                //第一次查詢數據庫.
                result = joinPoint.proceed();    //執行目標方法.
                System.out.println("AOP執行數據庫操作");
                //2.將數據保存到redis中
                String json = ObjectMapperUtil.toJSON(result);
                if(cacheFind.seconds()>0) //表示需要設定超時時間
                    jedis.setex(key, cacheFind.seconds(), json);
                else
                    //不需要超時
                    jedis.set(key, json);
            }
            return result;
        } catch (Throwable throwable) {
            throwable.printStackTrace();
            throw new RuntimeException(throwable);  //將檢查異常,轉化為運行時異常
        }
    }
}

4. 測試

假設下面為service層的方法

@CacheFind(key = "FIND_NAME")
public String findName() {
    return "hello world";
}

在controller中調用, 多次請求此controller的結果

AOP執行數據庫操作
AOP實現緩存查詢!!!!
AOP實現緩存查詢!!!!
AOP實現緩存查詢!!!!
......


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM