AOP-Redis缓存
我没有单独使用过Redis,细节我可能解释不到位。该文章是采用依赖注入实现AOP-Redis缓存功能的 、
之前有写实现Memory缓存的。异曲同工之妙。
使用Redis离不开安装get包:StackExchange.Redis.
操作流程:
- 创建一个RedisAOP的.cs文件。继承IInterceptor的接口,允许程序进行拦截。该接口应该依赖于Autofac,所以依赖注入最好使用AUtofac。
- 实现接口的方法Intercept。拦截的功能的操作主要在此处执行。
- 老张的项目是有一个baseAop的,因为RedisAOP和MemoryAOP都是属于缓存,有公共的方法。例如截取Key值等。初学我就不搞太麻烦了。一个一个手写比较容易记住。
- 定义一个接口一个实现。IRedisCaching,RedisCaching。该实现主要是向Redis存储值和取值。所以定义两个方法,Get获取缓存,Set存入缓存。
- RedisCaching里依赖注入ConnectionMultiplexer、这个代表Redis的连接字符串对象(应该可以这么理解,也可能我说的不太准确)。通过该对象的GetDatabase()获取redis内的数据库链接对象。然后使用StringGet,或者StringSet来存储或读取缓存。
- 将接口注入到第一步的RedisAOP中,让我们可以进行操作Redis。
- 很重要的一部分。将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缓存的更多相关文章
- ssm+redis 如何更简洁的利用自定义注解+AOP实现redis缓存
基于 ssm + maven + redis 使用自定义注解 利用aop基于AspectJ方式 实现redis缓存 如何能更简洁的利用aop实现redis缓存,话不多说,上demo 需求: 数据查询时 ...
- spring aop搭建redis缓存
SpringAOP与Redis搭建缓存 近期项目查询数据库太慢,持久层也没有开启二级缓存,现希望采用Redis作为缓存.为了不改写原来代码,在此采用AOP+Redis实现. 目前由于项目需要,只需要做 ...
- Redis缓存的使用
首先需要去Redis官网下载Redis的安装包 要在eclipse中使用Redis还需要两个jar包,需要的自行查找或者联系我 运行Redis需要开启Redis的服务端,也就是下载的安装包中的“red ...
- 使用方法拦截机制在不修改原逻辑基础上为 spring MVC 工程添加 Redis 缓存
首先,相关文件:链接: https://pan.baidu.com/s/1H-D2M4RfXWnKzNLmsbqiQQ 密码: 5dzk 文件说明: redis-2.4.5-win32-win64.z ...
- redis缓存在项目中的使用
关于redis为什么能作为缓存这个问题我们就不说了,直接来说一下redis缓存到底如何在项目中使用吧: 1.redis缓存如何在项目中配置? 1.1redis缓存单机版和集群版配置?(redis的客户 ...
- SpringBoot微服务电商项目开发实战 --- Redis缓存雪崩、缓存穿透、缓存击穿防范
最近已经推出了好几篇SpringBoot+Dubbo+Redis+Kafka实现电商的文章,今天再次回到分布式微服务项目中来,在开始写今天的系列五文章之前,我先回顾下前面的内容. 系列(一):主要说了 ...
- springboot整合redis缓存一些知识点
前言 最近在做智能家居平台,考虑到家居的控制需要快速的响应于是打算使用redis缓存.一方面减少数据库压力另一方面又能提高响应速度.项目中使用的技术栈基本上都是大家熟悉的springboot全家桶,在 ...
- springboot 用redis缓存整合spring cache注解,使用Json序列化和反序列化。
springboot下用cache注解整合redis并使用json序列化反序列化. cache注解整合redis 最近发现spring的注解用起来真的是很方便.随即产生了能不能吧spring注解使用r ...
- 缓存机制总结(JVM内置缓存机制,MyBatis和Hibernate缓存机制,Redis缓存)
一.JVM内置缓存(值存放在JVM缓存中) 我们可以先了解一下Cookie,Session,和Cache Cookie:当你在浏览网站的时候,WEB 服务器会先送一小小资料放在你的计算机上,Cooki ...
- 第04项目:淘淘商城(SpringMVC+Spring+Mybatis)【第七天】(redis缓存)
https://pan.baidu.com/s/1bptYGAb#list/path=%2F&parentPath=%2Fsharelink389619878-229862621083040 ...
随机推荐
- 使用 KubeKey 在 AWS 高可用部署 Kubernetes
作者:李耀宗 介绍 对于生产环境,我们需要考虑 Kubernetes 集群的高可用性.本文教您部署如何在多台 AWS EC2 实例快速部署一套高可用的生产环境.要满足 Kubernetes 集群服务需 ...
- 使用 GitLab 账号登陆 KubeSphere
作者:李帅 介绍 KubeSphere 多租户是实际生产使用中非常需要的一个功能,该功能满足不同用户登陆 KubeSphere 平台的需求.比如开发,运维,测试都需要登陆 KubeSphere 平台, ...
- 2024SHCTF--Crypto--Week1&Week2--WP
2024SHCTF 注:针对2024SHCTF赛事,写下自己的解题思路以及个别赛题赛后复现对于题目而产生的理解. Week1 d_known task: from Crypto.Util.number ...
- 9.Kubernetes核心技术-Controller
Kubernetes核心技术-Controller 内容 什么是Controller Pod和Controller的关系 Deployment控制器应用场景 yaml文件字段说明 Deployment ...
- 我们有40%代码是 AI 写的
- equals与”==”的区别
本文由 ImportNew - 刘志军 翻译自 Javarevisited.如需转载本文,请先参见文章末尾处的转载要求. equals()和"=="操作用于对象的比较,检查俩对象的 ...
- 性能检测工具之Lighthouse
转载:https://mp.weixin.qq.com/s?src=11×tamp=1618929340&ver=3020&signature=oXyx*RDLXjN ...
- 150页的剑指Offer解答PDF,它来了!!!
它来了!!! 终于整理出了第一版剑指Offer的PDF,主要以Java语言为主,一共67道题,100多页. 领取方式如下(无套路直接获取百度网盘的 链接,如果链接失效可以直接找我): [秦怀杂货店]公 ...
- 表里不一--限制容器内存4G,free还是32G
前言 最近有个新同事问了我一个问题,明明通过limit给容器内存限制了4G,为什么进容器看到的还是宿主机的内存32G docker run -it --rm -m 512m ubuntu:18.04 ...
- cnpm : 无法加载文件 cnpm.ps1
两种方法,本人用的第二种有效 一 安装 cnpm 命令行 npm install -g cnpm --registry=https://registry.npm.taobao.org 在使用 powe ...