概述
CacheModule也是一个Autofac模块。
一、CacheModule类
CacheModule将DefaultCacheManager注册为ICacheManager:
public class CacheModule : Module {
protected override void Load( ContainerBuilder builder) {
builder.RegisterType<DefaultCacheManager>()
.As< ICacheManager>()
.InstancePerDependency();
}
//...
}
如果类有一个接受ICacheManager型的参数的构造函数,Autofac容器在解析(Resolve)该类生成对象之前,会先解析一个ICacheManager型对象作为参数:
public class CacheModule : Module {
//...
protected override void AttachToComponentRegistration(Autofac.Core. IComponentRegistry componentRegistry, Autofac.Core.IComponentRegistration registration) {
var needsCacheManager = registration.Activator.LimitType
.GetConstructors()
.Any(x => x.GetParameters()
.Any(xx => xx.ParameterType == typeof(ICacheManager )));
if (needsCacheManager) {
registration.Preparing += (sender, e) => {
var parameter = new TypedParameter(
typeof(ICacheManager ),
e.Context.Resolve< ICacheManager>(new TypedParameter( typeof(Type ), registration.Activator.LimitType)));
e.Parameters = e.Parameters.Concat( new[] { parameter });
};
}
}
}
Cache Manager是与类型相关的,这实际上是CacheModule存在的意义所在。比如Orchard.Environment.DefaultOrchardHost和其他类型不会共享同一个DefaultCacheManager对象。
二、DefaultCacheManager:ICacheManager类
DefaultCacheManager类公开了两个方法:
public ICache <TKey, TResult> GetCache<TKey, TResult>() {
return _cacheHolder.GetCache<TKey, TResult>(_component);
}
public TResult Get<TKey, TResult>(TKey key, Func< AcquireContext<TKey>, TResult> acquire) {
return GetCache<TKey, TResult>().Get(key, acquire);
}
第 一个方法可以获取类型相关的ICache<TKey,TResult>(Cache<TKey,TResult>)对象集合;第 二个方法通过Key值获取具体的某一个Cache Result,即实际的缓存值。Cache<TKey,TResult>会在下面介绍。
不难看出,DefaultCacheManager是对ICacheHolder的简单封装,就算没有DefaultCacheManager类,也可以不怎么方便地使用缓存机制,因为实际的缓存存取是交给ICacheHolder来处理的,默认使用的是DefaultCacheHolder,这是一个应用程序域级的单例。
三、DefaultCacheHolder:ICacheHolder类
绝大多数的缓存机制都是采用字典的形式,DefaultCacheHolder中使用线程安全的ConcurrentDictionary<CacheKey, object>型字典来保存缓存,这里称为类型缓存字典,注意该字典中并不存储实际的缓存值。为了方便,在这里我们把CacheKey称为类型缓存字典Key;object称为类型缓存字典Value, 实际类型为泛型Cache<TKey,TResult>:ICache<TKey,TResult>的封闭类型。 Cache<TKey,Result>内部也有一个字典,类型为ConcurrentDictionary<TKey, CacheEntry>。在这里,TKey称为缓存字典Key,CacheEntry称为缓存字典Value。
CacheEntry有一个类型为TResult名为Result的属性,这里称为缓存Result,这才是实际的缓存值。
在分析源码的时候要特别区分这些我们约定的概念:
1、类型缓存字典、类型缓存字典Key、类型缓存字典Value
2、缓存字典、缓存字典Key、缓存字典Value和缓存Result。
在使用缓存时,我们是通过"缓存字典Key"来获取一个"缓存Result"。
DefaultCacheHolder仅公开了一个GetCache方法:
public ICache<TKey, TResult> GetCache<TKey, TResult>(Type component) {
var cacheKey = new CacheKey(component, typeof(TKey), typeof (TResult));
var result = _caches.GetOrAdd(cacheKey, k => new Cache<TKey, TResult>(_cacheContextAccessor));
return (Cache <TKey, TResult>)result;
}
方法首先使用两个泛型参数的类型加上一个方法参数(Type型),可以构成一个CacheKey。CacheKey是一个三
元组:
class CacheKey : Tuple<Type, Type , Type> {
public CacheKey(Type component, Type key, Type result)
: base(component, key, result) {
}
}
然后从类型缓存字典中获取一个Cache<TKey, TResult>:ICache<TKey,TResult>对象。这时可以认为获取了一个类型相关的缓存字典。调用Cache<TKey, TResult>对象Get方法获取实际的缓存值。
DefaultCacheHolder 采用延迟缓存机制,在第一次从缓存中获取对象时才会去构建对象;提供可扩展的缓存到期、更新策略,比如使用Orchard.Services.Clock 类配合可以让缓存在某个具体的时间到期或一定时间间隔到期。缓存过期并不表示它在内存中被立即销毁,而是会在下一次尝试获取缓存的时候重新生成缓存。
相关类型(皆在Orchard.Caching命名空间下):
DefaultCacheManager : ICacheManager
DefaultCacheHolder : ICacheHolder
DefaultCacheContextAccessor : ICacheContextAccessor
DefaultParallelCacheContext : IParallelCacheContext
DefaultAsyncTokenProvider : IAsyncTokenProvider
AcquireContext<TKey>:IAcquireContext
SimpleAcquireContext : IAcquireContext
Signals : ISignals : IVolatileProvider : ISingletonDependency
Signals.Token : IVolatileToken(Private nested class)
Cache<TKey, TResult> : ICache<TKey, TResult>
CacheEntry(Private class)
Weak<T>
参考资料:
- Orchard源码分析(5):Host相关(Orchard.Environment.DefaultOrchardHost类)
概述 Host 是应用程序域级的单例,代表了Orchard应用程序.其处理应用程序生命周期中的初始化.BeginRequest事件.EndRequest事件等. 可以简单理解为HttpApplicat ...
- Spring源码分析——BeanFactory体系之抽象类、类分析(二)
上一篇分析了BeanFactory体系的2个类,SimpleAliasRegistry和DefaultSingletonBeanRegistry——Spring源码分析——BeanFactory体系之 ...
- Orchard源码分析(1):Orchard架构
本文主要参考官方文档"How Orchard works"以及Orchardch上的翻译. 源码分析应该做到庖丁解牛,而不是以管窥豹或瞎子摸象.所以先对Orchard架构有 ...
- Spring源码分析——BeanFactory体系之抽象类、类分析(一)
上一篇介绍了BeanFactory体系的所有接口——Spring源码分析——BeanFactory体系之接口详细分析,本篇就接着介绍BeanFactory体系的抽象类和接口. 一.BeanFactor ...
- Thinkphp源码分析系列(二)–引导类
在上一章我们说到,ThinkPHP.php在设置完框架所需要的变量和调教好环境后,在最后调用了 Think\Think::start(); 即Think命名空间中的Think类的静态方法start ...
- spring源码分析系列 (5) spring BeanFactoryPostProcessor拓展类PropertyPlaceholderConfigurer、PropertySourcesPlaceholderConfigurer解析
更多文章点击--spring源码分析系列 主要分析内容: 1.拓展类简述: 拓展类使用demo和自定义替换符号 2.继承图UML解析和源码分析 (源码基于spring 5.1.3.RELEASE分析) ...
- Netty源码分析第8章(高性能工具类FastThreadLocal和Recycler)---->第1节: FastThreadLocal的使用和创建
Netty源码分析第八章: 高性能工具类FastThreadLocal和Recycler 概述: FastThreadLocal我们在剖析堆外内存分配的时候简单介绍过, 它类似于JDK的ThreadL ...
- Netty源码分析第8章(高性能工具类FastThreadLocal和Recycler)---->第2节: FastThreadLocal的set方法
Netty源码分析第八章: 高性能工具类FastThreadLocal和Recycler 第二节: FastThreadLocal的set方法 上一小节我们学习了FastThreadLocal的创建和 ...
- Netty源码分析第8章(高性能工具类FastThreadLocal和Recycler)---->第3节: recycler的使用和创建
Netty源码分析第八章: 高性能工具类FastThreadLocal和Recycler 第三节: recycler的使用和创建 这一小节开始学习recycler相关的知识, recycler是n ...
- Netty源码分析第8章(高性能工具类FastThreadLocal和Recycler)---->第4节: recycler中获取对象
Netty源码分析第八章: 高性能工具类FastThreadLocal和Recycler 第四节: recycler中获取对象 这一小节剖析如何从对象回收站中获取对象: 我们回顾上一小节demo的ma ...
随机推荐
- Web 安全:隐藏服务版本号
前述 为了防止一些恶意用户对 apache.nginx.php 等显示出来的版本信息进行攻击,生产环境需要关闭 web 服务的版本信息: apache 隐藏版本号 修改 httpd.conf,添加如下 ...
- WordPress的have_posts()和the_post()用法解析
原文地址:http://www.phpvar.com/archives/2316.html 网上找到一篇介绍WordPress的have_posts()和the_post()用法解析的文章,觉得不错! ...
- VS2015 安装mvc4安装包以及vs2010 sp1后导致Razor语法失效代码不高亮(能正常运行)/视图页面无法智能提示(.cshtml)解决办法
VS2015默认asp.net mvc 版本为5.0以上,默认不支持创建5.0以下的版本.所以想要使用mvc 4.0只能单独安装.在网上搜了几篇教程后在微软官网下载了Visual Studio 201 ...
- win7 系统无法复制粘贴解决方案
用远程桌面登陆服务器不能在本机和远程服务器之间粘贴文本了,即不能从本机复制文本粘贴到服务器,也不能从服务器复制文本粘贴到本机. 以下是解决方法之一,试了几次都很管用户:在服务器上打开任务管理器,查看进 ...
- java高新技术-代理
程序中代理的概念与作用 要为已存在的多个具有相同接口的目标类的各个方法增加一些系统功能,例如,异常处理.日志.计算方法的运行时间.事务管理.等等. 代理架构图: 如果采用工厂模式和配置文件的方式进行管 ...
- 【BZOJ-2400】Spoj839Optimal Marks 最小割 + DFS
2400: Spoj 839 Optimal Marks Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 567 Solved: 202[Submit ...
- 初识echarts
show一个demo而已
- 解析window.open链接的参数
); var arr = new Array(); arr = str.split("&"); ){ ; i<arr.length; i++){ ){ ); if(p ...
- Swift 函数做参数和闭包做参数的一个细节差别
函数作参数,示例为传入一个String和一个添加前缀的函数,返回一个添加完前缀的String: func demo(str:String,addPrefix:(String)->String)- ...
- 遵循PSR-4的自动加载
一.简介 首先这里要了解PSR,Proposing a Standards Recommendation(提出标准建议)的缩写,就是一种PHP开发规范,让我们研发出来的代码更合理.更好维护.可读性更高 ...