我没有单独使用过Redis,细节我可能解释不到位。该文章是采用依赖注入实现AOP-Redis缓存功能的 、

之前有写实现Memory缓存的。异曲同工之妙。

使用Redis离不开安装get包:StackExchange.Redis.

操作流程:

  1. 创建一个RedisAOP的.cs文件。继承IInterceptor的接口,允许程序进行拦截。该接口应该依赖于Autofac,所以依赖注入最好使用AUtofac。
  2. 实现接口的方法Intercept。拦截的功能的操作主要在此处执行。
  3. 老张的项目是有一个baseAop的,因为RedisAOP和MemoryAOP都是属于缓存,有公共的方法。例如截取Key值等。初学我就不搞太麻烦了。一个一个手写比较容易记住。
  4. 定义一个接口一个实现。IRedisCaching,RedisCaching。该实现主要是向Redis存储值和取值。所以定义两个方法,Get获取缓存,Set存入缓存。
  5. RedisCaching里依赖注入ConnectionMultiplexer、这个代表Redis的连接字符串对象(应该可以这么理解,也可能我说的不太准确)。通过该对象的GetDatabase()获取redis内的数据库链接对象。然后使用StringGet,或者StringSet来存储或读取缓存。
  6. 将接口注入到第一步的RedisAOP中,让我们可以进行操作Redis。
  7. 很重要的一部分。将IRedisCaching和RedisCaching注入程序,以至于我们可以依赖注入在RedisAOP中使用。其次!!!很重要的一部分不能忘记ConnectionMultiplexer也要注入进去!!!我一开始因为不常用redis。脑子抽抽忘记了。
  • RedisAOP代码

    public class RedisAOP : IInterceptor
    {
    protected readonly IRedisCaching redis; public RedisAOP(IRedisCaching _redis)
    {
    this.redis = _redis;
    }
    public void Intercept(IInvocation invocation)
    {
    var method = invocation.MethodInvocationTarget ?? invocation.Method;
    //获取自定义缓存键
    var cacheKey = CustomCacheKey(invocation);
    //根据key获取相应的缓存值
    var cacheValue = redis.GetValue(cacheKey).Result;
    if (cacheValue != null)
    {
    //动态返回类型
    Type returnType;
    //获取传入方法的返回类型。如果是多个就取默认第一个
    if (typeof(Task).IsAssignableFrom(method.ReturnType))
    {
    returnType = method.ReturnType.GenericTypeArguments.FirstOrDefault();
    }
    else
    {
    returnType = method.ReturnType;
    }
    //将数据解析成方法返回类型
    dynamic _result = JsonSerializer.Deserialize(cacheValue, returnType);
    invocation.ReturnValue = (typeof(Task).IsAssignableFrom(method.ReturnType)) ? Task.FromResult(_result) : _result;
    return;
    }
    //去执行当前的方法
    invocation.Proceed();
    //存入缓存
    if (!string.IsNullOrWhiteSpace(cacheKey))
    {
    redis.Set(cacheKey, invocation.ReturnValue,TimeSpan.FromHours(24));
    }
    } /// <summary>
    /// object 转 string
    /// </summary>
    /// <param name="arg"></param>
    /// <returns></returns>
    protected static string GetArgumentValue(object arg)
    {
    if (arg is DateTime || arg is DateTime?)
    {
    return ((DateTime)arg).ToString("yyyyMMddHHmmss");
    } if (arg is string || arg is ValueType || arg is Nullable)
    {
    return arg.ToString();
    } if (arg != null)
    {
    if (arg.GetType().IsClass)
    {
    return MD5Helper.MD5Encrypt16(JsonSerializer.Serialize(arg));
    }
    } return string.Empty;
    } /// <summary>
    /// 自定义缓存的key
    /// </summary>
    /// <param name="invocation"></param>
    /// <returns></returns>
    protected string CustomCacheKey(IInvocation invocation)
    {
    var typeName = invocation.TargetType.Name;
    var methodName = invocation.Method.Name;
    var methodArguments = invocation.Arguments.Select(GetArgumentValue).Take(3).ToList();//获取参数列表,最多三个 string key = $"{typeName}:{methodName}:";
    foreach (var param in methodArguments)
    {
    key = $"{key}{param}:";
    }
    return key.TrimEnd(':');
    }
    }
  • IRedisCaching/RedisCaching代码

    public class RedisCaching : IRedisCaching
    {
    private readonly ConnectionMultiplexer redis;
    private readonly IDatabase database;
    public RedisCaching(ConnectionMultiplexer _redis)
    {
    this.redis = _redis;
    database = _redis.GetDatabase();
    }
    /// <summary>
    /// 获取值
    /// </summary>
    /// <param name="key"></param>
    /// <returns></returns>
    public async Task<string> GetValue(string key)
    {
    return await database.StringGetAsync(key);
    }
    /// <summary>
    /// 存储值
    /// </summary>
    /// <param name="key"></param>
    /// <param name="value"></param>
    /// <param name="cacheTime">过期时间</param>
    /// <returns></returns>
    /// <exception cref="NotImplementedException"></exception>
    public async Task Set(string key, object value, TimeSpan cacheTime)
    {
    if (value != null)
    {
    if (value is string cacheValue)
    {
    // 字符串无需序列化
    await database.StringSetAsync(key, cacheValue, cacheTime);
    }
    else
    {
    //序列化,将object值生成RedisValue
    await database.StringSetAsync(key, JsonSerializer.Serialize(value), cacheTime);
    }
    }
    }
    }
  • 注入相关的接口,和Redis
    //接口
    builder.Services.AddSingleton<IRedisCaching,RedisCaching>();
    //Redis
    builder.Services.AddSingleton<ConnectionMultiplexer>(sp =>
    {
    //获取连接字符串
    string redisConfiguration = "127.0.0.1:6678,password=123456";
    var configuration = ConfigurationOptions.Parse(redisConfiguration, true);
    configuration.ResolveDns = true;
    return ConnectionMultiplexer.Connect(configuration);
    });
  • 使用Autofac将AOP文件注册到服务的程序集中
               var assemblysServicesPath = Path.Combine(basePath, "DogService");
    
                builder.RegisterType<LogAOP>();//可以直接替换其他拦截器!一定要把拦截器进行注册
    builder.RegisterType<RedisAOP>(); //注入仓储
    var assemblysRepository = Assembly.LoadFrom(assemblysRepositoryPath);
    builder.RegisterAssemblyTypes(assemblysRepository)
    .AsImplementedInterfaces()//方法表示将组件以其实现的接口类型进行注册,这样在进行依赖注入时,可以根据接口类型获取相应的实现类
    .PropertiesAutowired()//方法用于自动装配属性依赖
    .InstancePerDependency()//方法表示每次请求时都创建一个新的实例。
    .EnableInterfaceInterceptors()//方法启用接口拦截,使得后续可以对注册的接口进行拦截。
    .InterceptedBy(typeof(LogAOP),typeof(RedisAOP));//表

完活!

AOP-Redis缓存的更多相关文章

  1. ssm+redis 如何更简洁的利用自定义注解+AOP实现redis缓存

    基于 ssm + maven + redis 使用自定义注解 利用aop基于AspectJ方式 实现redis缓存 如何能更简洁的利用aop实现redis缓存,话不多说,上demo 需求: 数据查询时 ...

  2. spring aop搭建redis缓存

    SpringAOP与Redis搭建缓存 近期项目查询数据库太慢,持久层也没有开启二级缓存,现希望采用Redis作为缓存.为了不改写原来代码,在此采用AOP+Redis实现. 目前由于项目需要,只需要做 ...

  3. Redis缓存的使用

    首先需要去Redis官网下载Redis的安装包 要在eclipse中使用Redis还需要两个jar包,需要的自行查找或者联系我 运行Redis需要开启Redis的服务端,也就是下载的安装包中的“red ...

  4. 使用方法拦截机制在不修改原逻辑基础上为 spring MVC 工程添加 Redis 缓存

    首先,相关文件:链接: https://pan.baidu.com/s/1H-D2M4RfXWnKzNLmsbqiQQ 密码: 5dzk 文件说明: redis-2.4.5-win32-win64.z ...

  5. redis缓存在项目中的使用

    关于redis为什么能作为缓存这个问题我们就不说了,直接来说一下redis缓存到底如何在项目中使用吧: 1.redis缓存如何在项目中配置? 1.1redis缓存单机版和集群版配置?(redis的客户 ...

  6. SpringBoot微服务电商项目开发实战 --- Redis缓存雪崩、缓存穿透、缓存击穿防范

    最近已经推出了好几篇SpringBoot+Dubbo+Redis+Kafka实现电商的文章,今天再次回到分布式微服务项目中来,在开始写今天的系列五文章之前,我先回顾下前面的内容. 系列(一):主要说了 ...

  7. springboot整合redis缓存一些知识点

    前言 最近在做智能家居平台,考虑到家居的控制需要快速的响应于是打算使用redis缓存.一方面减少数据库压力另一方面又能提高响应速度.项目中使用的技术栈基本上都是大家熟悉的springboot全家桶,在 ...

  8. springboot 用redis缓存整合spring cache注解,使用Json序列化和反序列化。

    springboot下用cache注解整合redis并使用json序列化反序列化. cache注解整合redis 最近发现spring的注解用起来真的是很方便.随即产生了能不能吧spring注解使用r ...

  9. 缓存机制总结(JVM内置缓存机制,MyBatis和Hibernate缓存机制,Redis缓存)

    一.JVM内置缓存(值存放在JVM缓存中) 我们可以先了解一下Cookie,Session,和Cache Cookie:当你在浏览网站的时候,WEB 服务器会先送一小小资料放在你的计算机上,Cooki ...

  10. 第04项目:淘淘商城(SpringMVC+Spring+Mybatis)【第七天】(redis缓存)

    https://pan.baidu.com/s/1bptYGAb#list/path=%2F&parentPath=%2Fsharelink389619878-229862621083040 ...

随机推荐

  1. Kubernetes 升级不弃 Docker:KubeKey 的丝滑之道

    作者:尹珉,KubeSphere Ambaasador&Contributor,KubeSphere 社区用户委员会杭州站站长. 引言 随着 Kubernetes 社区的不断发展,即将迎来 K ...

  2. 云原生周刊:CNCF 宣布 Falco 毕业|2024.3.4

    开源项目推荐 ldap-operator 用于部署和管理 LDAP 目录的 Kubernetes Operator. Updatecli Updatecli 是一个用于应用文件更新策略的工具.每个应用 ...

  3. 云原生周刊:K8sGPT 加入 CNCF | 2024.1.8

    开源项目推荐 VolSync VolSync 使用 rsync 或 rclone 在集群之间异步复制 Kubernetes 持久卷.它还支持通过 Restic 创建持久卷的备份. KubeClarit ...

  4. Readme 《Machine Learning by Andrew NG》

    本文系列内容是吴恩达老师的机器学习公开课的文本对应.需要具备英文,微积分,线性代数,程序设计的基础.从第二周开始有编程作业,到第九周.总共8个作业.感谢吴恩达老师⸜₍๑•⌔•๑ ₎⸝ 2021年9月1 ...

  5. winform计算器

    引言 本次项目目的主要为了熟悉winform控件使用,以及学习Microsoft.CSharp的使用. 技术栈 C# winform 实现效果 设计与实现 按键使用button空间,计算算式以及计算结 ...

  6. Oracle-表分析和索引分析解读

    概述当表没有做分析的时候,Oracle 会使用动态采样来收集统计信息. 获取准确的段对象(表,表分区,索引等)的分析数据,是CBO存在的基石,CBO的机制就是收集尽可能多的对象信息和系统信息,通过对这 ...

  7. 如何使用Ida Pro和Core Dump文件定位崩溃位置(Linux下无调试符号的进程专享)

    我们在嵌入式Linux开发过程中经常会遇到一个问题,就是程序崩溃后不知道具体位置.因为我们发布到生产环境的一般是没有调试符号的(使用strip或编译时加-s参数,CMake生成的编译指令中的-O3也会 ...

  8. [解决方案] 几种通过 iproute2 来打通不同节点间容器网络的方式

    几种通过 iproute2 来打通不同节点间容器网络的方式 几种通过 iproute2 来打通不同节点间容器网络的方式 host-gw ipip vxlan 背景 之前由于需要打通不同节点间的容器网络 ...

  9. xtrabackup进行mysql数据库备份、还原

    xtrabackup简介 前面介绍mysqldump备份方式是采用逻辑备份,其最大的缺陷就是备份和恢复速度都慢,对于一个小于50G的数据库而言,这个速度还是能接受的,但如果数据库非常大,那再使用mys ...

  10. ARC133D Range XOR

    ARC133D Range XOR 题目链接:[ARC133D] Range XOR 非常好数位 dp. 思路 根据异或的前缀和,我们可以把式子化成这样. \[\sum_{i=l}^r\sum_{j= ...