欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

如何打造redis緩存組件

 更新時間:2024年12月09日 17:08:38   作者:阿花落知多少  
文章介紹了如何使用熱插拔AOP、反射、Redis自定義注解和SpringEL表達(dá)式來打造一個優(yōu)雅的Redis緩存組件,通過這種方式,可以重構(gòu)和簡化緩存代碼,并提供了Redis配置和自定義注解的詳細(xì)說明,文章還包含了AOP測試的總結(jié),并鼓勵讀者參考和支持

打造redis緩存組件

使用熱插拔aop+反射+redis自定義注解+spring EL表達(dá)式打造redis緩存組件,優(yōu)雅重構(gòu)緩存代碼

redis配置

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

@Configuration
@EnableAspectJAutoProxy //V2  開啟AOP自動代理
public class RedisConfig
{
    /**
     * @param lettuceConnectionFactory
     * @return
     *
     * redis序列化的工具配置類,下面這個請一定開啟配置
     * 127.0.0.1:6379> keys *
     * 1) "ord:102"  序列化過
     * 2) "\xac\xed\x00\x05t\x00\aord:102"   野生,沒有序列化過
     */
    @Bean
    public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory lettuceConnectionFactory)
    {
        RedisTemplate<String,Object> redisTemplate = new RedisTemplate<>();

        redisTemplate.setConnectionFactory(lettuceConnectionFactory);
        //設(shè)置key序列化方式string
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        //設(shè)置value的序列化方式j(luò)son
        redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());

        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());

        redisTemplate.afterPropertiesSet();

        return redisTemplate;
    }
}

自定義注解

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 MyRedisCache     //@EnableAspectJAutoProxy //啟AOP自動代理
{
    //約等于鍵的前綴prefix,
    String keyPrefix();

    //SpringEL表達(dá)式,解析占位符對應(yīng)的匹配value值
    String matchValue();
}

AOP

import jakarta.annotation.Resource;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.DefaultParameterNameDiscoverer;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.stereotype.Component;
import org.aspectj.lang.reflect.MethodSignature;

import java.lang.reflect.Method;
import java.util.Objects;


@Component
@Aspect
public class MyRedisCacheAspect
{
    @Resource
    private RedisTemplate redisTemplate;

    //配置織入點(diǎn)
    @Pointcut("@annotation(com.atguigu.interview2.annotations.MyRedisCache)")
    public void cachePointCut(){}

    @Around("cachePointCut()")
    public Object doCache(ProceedingJoinPoint joinPoint)
    {
        Object result = null;


        /**
         *     @MyRedisCache(keyPrefix = "user",matchValue = "#id")
         *     public User getUserById(Integer id)
         *     {
         *         return userMapper.selectByPrimaryKey(id);
         *     }
         */


        try
        {
            //1 獲得重載后的方法名
            MethodSignature signature = (MethodSignature) joinPoint.getSignature();
            Method method = signature.getMethod();

            //2 確定方法名后獲得該方法上面配置的注解標(biāo)簽MyRedisCache
            MyRedisCache myRedisCacheAnnotation = method.getAnnotation(MyRedisCache.class);

            //3 拿到了MyRedisCache這個注解標(biāo)簽,獲得該注解上面配置的參數(shù)進(jìn)行封裝和調(diào)用
            String keyPrefix = myRedisCacheAnnotation.keyPrefix();
            String matchValueSpringEL = myRedisCacheAnnotation.matchValue();

            //4 SpringEL 解析器
            ExpressionParser parser = new SpelExpressionParser();
            Expression expression = parser.parseExpression(matchValueSpringEL);//#id
            EvaluationContext context = new StandardEvaluationContext();

            //5 獲得方法里面的形參個數(shù)
            Object[] args = joinPoint.getArgs();
            DefaultParameterNameDiscoverer discoverer = new DefaultParameterNameDiscoverer();
            String[] parameterNames = discoverer.getParameterNames(method);
            for (int i = 0; i < parameterNames.length; i++)
            {
                System.out.println("獲得方法里參數(shù)名和值: "+parameterNames[i] + "\t" + args[i].toString());
                context.setVariable(parameterNames[i], args[i].toString());
            }

            //6 通過上述,拼接redis的最終key形式
            String key = keyPrefix + ":" + expression.getValue(context).toString();
            System.out.println("------拼接redis的最終key形式: " + key);

            //7 先去redis里面查詢看有沒有
            result = redisTemplate.opsForValue().get(key);
            if (result != null)
            {
                System.out.println("------redis里面有,我直接返回結(jié)果不再打擾mysql: " + result);
                return result;
            }

            //8 redis里面沒有,去找msyql查詢或叫進(jìn)行后續(xù)業(yè)務(wù)邏輯
            //-------aop精華部分,才去找findUserById方法干活
            //userMapper.selectByPrimaryKey(id);
            result = joinPoint.proceed();//主業(yè)務(wù)邏輯查詢mysql,放行放行放行

            //9 mysql步驟結(jié)束,還需要把結(jié)果存入redis一次,緩存補(bǔ)償
            if (result != null)
            {
                System.out.println("------redis里面無,還需要把結(jié)果存入redis一次,緩存補(bǔ)償: " + result);
                redisTemplate.opsForValue().set(key, result);
            }
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }

        return result;
    }
}

測試

    /**
     * 會將返回值存進(jìn)redis里,key生成規(guī)則需要程序員用SpEL表達(dá)式自己指定,value就是程序從mysql查出并返回的user
     * redis的key 等于  keyPrefix:matchValue
     */
    @Override
    @MyRedisCache(keyPrefix = "user",matchValue = "#id")
    public User getUserById(Integer id)
    {
        return userMapper.selectByPrimaryKey(id);
    }

總結(jié)

以上為個人經(jīng)驗(yàn),希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • CentOS下Redis數(shù)據(jù)庫的基本安裝與配置教程

    CentOS下Redis數(shù)據(jù)庫的基本安裝與配置教程

    這篇文章主要介紹了CentOS下Redis數(shù)據(jù)庫的基本安裝與配置教程,Redis一般被用作基于內(nèi)存的緩存式數(shù)據(jù)存儲,要的朋友可以參考下
    2015-12-12
  • Redis字符串類型的常用命令小結(jié)

    Redis字符串類型的常用命令小結(jié)

    這篇文章給大家整理了在操作Redis字符串類型中的常用命令,文章總結(jié)的很全面,對大家學(xué)習(xí)Redis具有一定的參考借鑒價值,下面來一起看看吧。
    2016-09-09
  • Redis服務(wù)器優(yōu)化方式

    Redis服務(wù)器優(yōu)化方式

    文章分享了常見的Redis服務(wù)器優(yōu)化技巧和策略,主要包括內(nèi)存管理、持久化配置、連接配置和網(wǎng)絡(luò)優(yōu)化四個方面,內(nèi)存管理主要是設(shè)置maxmemory參數(shù)和選擇合適的內(nèi)存淘汰策略,持久化配置包括RDB持久化和AOF持久化
    2024-09-09
  • Redis過期Key刪除策略和內(nèi)存淘汰策略的實(shí)現(xiàn)

    Redis過期Key刪除策略和內(nèi)存淘汰策略的實(shí)現(xiàn)

    當(dāng)內(nèi)存使用達(dá)到上限,就無法存儲更多數(shù)據(jù)了,為了解決這個問題,Redis內(nèi)部會有兩套內(nèi)存回收的策略,過期Key刪除策略和內(nèi)存淘汰策略,本文就來詳細(xì)的介紹一下這兩種方法,感興趣的可以了解一下
    2024-02-02
  • redis適合場景八點(diǎn)總結(jié)

    redis適合場景八點(diǎn)總結(jié)

    在本篇文章中我們給大家整理了關(guān)于redis適合什么場景的8點(diǎn)知識點(diǎn)內(nèi)容,需要的朋友們參考下。
    2019-06-06
  • RedisTemplate中boundHashOps的使用小結(jié)

    RedisTemplate中boundHashOps的使用小結(jié)

    redisTemplate.boundHashOps(key)?是 RedisTemplate 類的一個方法,本文主要介紹了RedisTemplate中boundHashOps的使用小結(jié),具有一定的參考價值,感興趣的可以了解一下
    2024-04-04
  • 詳解Redis基本命令與使用場景

    詳解Redis基本命令與使用場景

    REmote DIctionary Server(Redis)是一個由Salvatore Sanfilippo寫的key-value 存儲系統(tǒng),是跨平臺的非關(guān)系型數(shù)據(jù)庫,是一個開源的使用ANSI C語言編寫、遵守BSD協(xié)議、支持網(wǎng)絡(luò)、可基于內(nèi)存、分布式、可選持久性的鍵值對(Key-Value)存儲數(shù)據(jù)庫,并提供多種語言的 API。
    2021-06-06
  • Redis集群Lettuce主從切換問題解決方案

    Redis集群Lettuce主從切換問題解決方案

    這篇文章主要為大家介紹了Redis集群Lettuce主從切換問題解決方案,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-07-07
  • redis-cli -p 6379 info命令詳解

    redis-cli -p 6379 info命令詳解

    這篇文章主要介紹了redis-cli -p 6379 info命令詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-12-12
  • 使用Redis命令操作數(shù)據(jù)庫的常見錯誤及解決方法

    使用Redis命令操作數(shù)據(jù)庫的常見錯誤及解決方法

    由于Redis是內(nèi)存數(shù)據(jù)庫,因此可能會存在一些安全問題,下面這篇文章主要給大家介紹了關(guān)于使用Redis命令操作數(shù)據(jù)庫的常見錯誤及解決方法,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-02-02

最新評論