AOP的姿势之 简化 MemoryCache 使用方式
0. 前言
之前写了几篇文章介绍了一些AOP的知识,
但是还没有亮出来AOP的姿势,
也许姿势漂亮一点,
大家会对AOP有点兴趣
内容大致会分为如下几篇:(毕竟人懒,一下子写完太累了,没有动力)
- AOP的姿势之 简化 MemoryCache 使用方式
- AOP的姿势之 简化混用 MemoryCache 和 DistributedCache 使用方式
- AOP的姿势之 如何把 HttpClient 变为声明式
至于AOP框架在这儿示例依然会使用我自己基于emit实现的动态代理AOP框架: https://github.com/fs7744/Norns.Urd
毕竟是自己写的,魔改/加功能都很方便,
万一万一大家如果有疑问,(虽然大概不会有),我也好回答, (当然如果大家认可,在github给个star,就实在是太让人开心了)
1. 正文
1.1 回顾 MemoryCache如何使用
var cache = ServiceProvider.GetRequiredService<IMemoryCache>();
var r = await cache.GetOrCreateAsync(cacheKey, async e =>
{
var rr = await do();
e.AbsoluteExpirationRelativeToNow = absoluteExpirationRelativeToNow;
return rr;
});
MemoryCache
本身已经被封装到如此简单就可以使用了
但是呢,每次我们使用的时候依然要这样重复写类似的代码
当然我们都是拥有超强的 ctrl+c 和 ctrl+v 能力,
这点点重复代码都是些毛毛雨啦,
上w行代码一把梭都是小场面了,
不过呢,这样的代码写的和在校的学生一样,
怎么能体现我们混迹江湖,加班数十载的逼格呢?
我们要让这些在校学生/实习生看不懂我们的代码,
让他们看不到GetOrCreateAsync
,
让他们调试的时候 do()
里面的断点跑不到
这样我们才能展示出扫地僧的实力:来,小朋友,我来教你新姿势
1.2 逼格启航
1.2.1 逼格核心 - 拦截器
在Norns.Urd中,Interceptor 拦截器是用户可以在方法插入自己的逻辑的核心。
标准结构为IInterceptor
public interface IInterceptor
{
// 用户可以通过Order自定义拦截器顺序,排序方式为ASC,全局拦截器和显示拦截器都会列入排序中
int Order { get; }
// 同步拦截方法
void Invoke(AspectContext context, AspectDelegate next);
// 异步拦截方法
Task InvokeAsync(AspectContext context, AsyncAspectDelegate next);
// 可以设置拦截器如何选择过滤是否拦截方法,除了这里还有NonAspectAttribute 和全局的NonPredicates可以影响过滤
bool CanAspect(MethodInfo method);
}
这里我们为了大家理解简单,就使用最简单的方式来做 : 使用 AbstractInterceptorAttribute
一个非常简单的例子就如下了:
public class CacheAttribute : AbstractInterceptorAttribute
{
private readonly TimeSpan absoluteExpirationRelativeToNow;
private readonly string cacheKey;
// 为了简单,缓存策略我们就先只支持TTL 存活固定时间
public CacheAttribute(string cacheKey, string absoluteExpirationRelativeToNow)
{
this.cacheKey = cacheKey;
this.absoluteExpirationRelativeToNow = TimeSpan.Parse(absoluteExpirationRelativeToNow);
}
public override async Task InvokeAsync(AspectContext context, AsyncAspectDelegate next)
{
// 整个代码基本和我们直接使用 MemoryCache 一样
var cache = context.ServiceProvider.GetRequiredService<IMemoryCache>();
var r = await cache.GetOrCreateAsync(cacheKey, async e =>
{
await next(context); // 所以真正实现的方法逻辑都在 next 中,所以调用它就好了
e.AbsoluteExpirationRelativeToNow = absoluteExpirationRelativeToNow;
return context.ReturnValue; // 结果都在ReturnValue , 这里为了简单,就不写 void / Task<T> / ValueTask<T> 等等 各种返回值的兼容代码了
});
context.ReturnValue = r; // 设置 ReturnValue, 由于缓存有效期内, next不会被调用, 所以ReturnValue不会有值,我们需要将缓存结果设置到 ReturnValue
}
}
1.2.2 测试一下
public interface ITestCacheClient
{
string Say(string v);
}
public class TestCacheClient : ITestCacheClient
{
public string Say(string v) => v;
}
static class Program
{
static void Main(string[] args)
{
var client = new ServiceCollection()
.AddMemoryCache()
.AddSingleton<ITestCacheClient, TestCacheClient>()
.ConfigureAop()
.BuildServiceProvider()
.GetRequiredService<ITestCacheClient>();
Console.WriteLine(client.Say("Hello World!"));
Console.WriteLine(client.Say("Hello Two!"));
Thread.Sleep(3000);
Console.WriteLine(client.Say("Hello Two!"));
}
}
Console 结果
Hello World!
Hello Two!
Hello Two!
加上缓存设置:
public class TestCacheClient : ITestCacheClient
{
[Cache(nameof(Say), "00:00:03")]
public string Say(string v) => v;
}
再次测试的 Console 结果
Hello World!
Hello World!
Hello Two!
例子代码都在 https://github.com/fs7744/AopDemoList/tree/master/MakeMemoryChacheSimple
处理情况更全面的例子在 https://github.com/fs7744/Norns.Urd/tree/main/src
祝大家都能愉快被叫 大神 nb。
AOP的姿势之 简化 MemoryCache 使用方式的更多相关文章
- AOP的姿势之 简化混用 MemoryCache 和 DistributedCache 的方式
0. 前言 之前写了几篇文章介绍了一些AOP的知识, 但是还没有亮出来AOP的姿势, 也许姿势漂亮一点, 大家会对AOP有点兴趣 内容大致会分为如下几篇:(毕竟人懒,一下子写完太累了,没有动力) AO ...
- 6.AOP配置与应用(xml的方式)
xml 配置 AOP 1.将 拦截其器对象 初始化到容器中 2.<aop:config> <aop:aspect.... <aop:pointcut <aop:befor ...
- AOP的具体实践-简化结果返回的处理
原因: 以前学习Spring的时候着重学习过AOP概念,但是一直也没有用上,唯一碰到过的就是Spring内置的事务管理.现在碰到过一些结果后面的操作适合用到,所以这里就拿出来用一下,并且复习一下落下的 ...
- SSH深度历险(十) AOP原理及相关概念学习+AspectJ注解方式配置spring AOP
AOP(Aspect Oriented Programming),是面向切面编程的技术.AOP基于IoC基础,是对OOP的有益补充. AOP之所以能得到广泛应用,主要是因为它将应用系统拆分分了2个部分 ...
- Dora.Interception,为.NET Core度身打造的AOP框架 [2]:以约定的方式定义拦截器
上一篇<更加简练的编程体验>提供了最新版本的Dora.Interception代码的AOP编程体验,接下来我们会这AOP框架的编程模式进行详细介绍,本篇文章着重关注的是拦截器的定义.采用“ ...
- Java 中 AOP —— 探讨其存在价值及实现方式对比
AOP 概述 Aspect-oriented programming(面向切面编程).最广为人知的面向侧面的程序设计语言是由施乐帕洛阿尔托研究中心 (施乐帕克 nb!)开发的AspectJ,该语言可以 ...
- 【学习】Spring 的 AOP :基于Annotation 的“零配置”方式
转自:http://www.cnblogs.com/jbelial/archive/2012/07/20/2539123.html AOP(Aspect Orient Programming ) , ...
- Spring 详解(二)------- AOP关键概念以及两种实现方式
目录 1. AOP 关键词 2. AOP 的作用 3. AOP 的通知类型 4. 基于 xml 的配置方式 5. 基于注解的配置方式 6. 切面的优先级 7. 重用切点表达式 8. 两种方式的比较(摘 ...
- Spring的AOP开发(基于AspectJ的XML方式)
Spring的AOP的简介: AOP思想最早是由AOP联盟组织提出的.Spring是使用这种思想最好的框架 Spring的AOP有自己实现的方式(非常繁琐). Aspect是一个AOP的框架, Spr ...
随机推荐
- 渗透入门rop
原文链接:https://blog.csdn.net/guiguzi1110/article/details/77663430?locationNum=1&fps=1 基本ROP 随着NX保护 ...
- IdentityServer4系列 | 简化模式
一.前言 从上一篇关于资源密码凭证模式中,通过使用client_id和client_secret以及用户名密码通过应用Client(客户端)直接获取,从而请求获取受保护的资源,但是这种方式存在clie ...
- springboot:读取application.yml文件
现在开发主要使用微服务框架springboot,在springboot中经常遇到读取application.yml文件的情形. 一.概述 开发过程中经常遇到要读取application.yml文件中的 ...
- activiti笔记
activiti笔记 核心api api介绍 1.ProcessEngine 说明: 1) 在Activiti中最核心的类,其他的类都是由他而来. 2) 产生方式: ProcessEngine pro ...
- 喜欢 Dapper 的朋友看过来,送一份厚礼
写在开头 众所周知 Dapper 是 .NET 下最轻最快的 ORM,它是喜欢写 SQL 码农的福音,相对于 SqlHelper 它更加方便,据统计 10个 .NETer 有 9个 用过 Dapper ...
- 【开发工具】 使用阿里的 Teambition 跟踪BUG修复及需求管理
刚入公司几个月,公司新项目一直没有用协作工具进行BUG管理,公司也没有专业的测试工程师. 第一阶段开发到了尾声,工作效率实在太低,随决定使用一个比较现代一点的管理工具. 在众多在线项目协作软件中,我选 ...
- GBK宽字节注入SQL
SQL注入:宽字节注入(GBK双字节绕过) 2015-06-09lyiang 宽字节注入的作用是非常大的,实际上在代码层的防御一般不外乎两种,一是反斜杠转义,而就是replace替换成空字节,之前的替 ...
- [BJDCTF 2nd]xss之光
[BJDCTF 2nd]xss之光 进入网址之后发现存在.git泄露,将源码下载下来,只有index.php文件 <?php $a = $_GET['yds_is_so_beautiful']; ...
- CNVD漏洞证书(2)
第二张CNVD的原创漏洞证书. 关于证书申请可以看我之前写的这篇博客: https://www.cnblogs.com/Cl0ud/p/12720413.html 继续加油
- 团队作业4-Day4
团队作业4-Day4 项目git地址 1. 站立式会议 2. 项目燃尽图 3. 适当的项目截图 4. 代码/文档签入记录(部分) 5. 每人每日总结 吴梓华:完成了排位模式与练习模式的界面实现,整合代 ...