zoukankan      html  css  js  c++  java
  • ABP框架详解(七)Caching

      在ABP框架中存在一个缓存机制,使用ICache的继承类来存储最终需要缓存的数据,可以吧ICache看成一个字典对象,使用Key作为真实数据的具有唯一性的表示。使用上与字典对象完全相同,Get方法传递Key,还有数据工厂作为参数就能返回最终的值,Set方法用于存储。包含一个TimeSpan属性用于指定最长不使用数据的过期时间。

    /// <summary>
        /// Defines a cache that can be store and get items by keys.
        /// </summary>
        public interface ICache : IDisposable
        {
            /// <summary>
            /// Unique name of the cache.
            /// </summary>
            string Name { get; }
    
            /// <summary>
            /// Default sliding expire time of cache items.
            /// Default value: 60 minutes. Can be changed by configuration.
            /// </summary>
            TimeSpan DefaultSlidingExpireTime { get; set; }
    
            /// <summary>
            /// Gets an item from the cache.
            /// </summary>
            /// <param name="key">Key</param>
            /// <param name="factory">Factory method to create cache item if not exists</param>
            /// <returns>Cached item</returns>
            object Get(string key, Func<string, object> factory);
    
            /// <summary>
            /// Gets an item from the cache.
            /// </summary>
            /// <param name="key">Key</param>
            /// <param name="factory">Factory method to create cache item if not exists</param>
            /// <returns>Cached item</returns>
            Task<object> GetAsync(string key, Func<string, Task<object>> factory);
    
            /// <summary>
            /// Gets an item from the cache or null if not found.
            /// </summary>
            /// <param name="key">Key</param>
            /// <returns>Cached item or null if not found</returns>
            object GetOrDefault(string key);
    
            /// <summary>
            /// Gets an item from the cache or null if not found.
            /// </summary>
            /// <param name="key">Key</param>
            /// <returns>Cached item or null if not found</returns>
            Task<object> GetOrDefaultAsync(string key);
    
            /// <summary>
            /// Saves/Overrides an item in the cache by a key.
            /// </summary>
            /// <param name="key">Key</param>
            /// <param name="value">Value</param>
            /// <param name="slidingExpireTime">Sliding expire time</param>
            void Set(string key, object value, TimeSpan? slidingExpireTime = null);
    
            /// <summary>
            /// Saves/Overrides an item in the cache by a key.
            /// </summary>
            /// <param name="key">Key</param>
            /// <param name="value">Value</param>
            /// <param name="slidingExpireTime">Sliding expire time</param>
            Task SetAsync(string key, object value, TimeSpan? slidingExpireTime = null);
    
            /// <summary>
            /// Removes a cache item by it's key.
            /// </summary>
            /// <param name="key">Key</param>
            void Remove(string key);
    
            /// <summary>
            /// Removes a cache item by it's key (does nothing if given key does not exists in the cache).
            /// </summary>
            /// <param name="key">Key</param>
            Task RemoveAsync(string key);
    
            /// <summary>
            /// Clears all items in this cache.
            /// </summary>
            void Clear();
    
            /// <summary>
            /// Clears all items in this cache.
            /// </summary>
            Task ClearAsync();
        }

      框架中提供了一个ICache的抽象实现类CacheBase,作为所有具体缓存方式的基类,实现了所有基础逻辑,最终的Cache对象只需继承CacheBase,并重写object GetOrDefault(string key),void Set(string key, object value, TimeSpan? slidingExpireTime = null),void Clear()等三个抽象方法就可以完成一个真实可用的缓存Cache(另外Dispose方法通常是需要重写)。同时CacheBase的所有其他公共方法也是可重写的。ABP中默认提供了一个以内存方式缓存数据的实现即AbpMemoryCache,只是简单实用微软的MemoryCache类作为内部缓存容器。

      ICacheManager使用单例模式用于管理所有的ICache,其中包含一个传递Key返回ICache的GetCache方法,还有一个返回所有ICache的GetAllCaches方法,在调用GetCache传递Key的时候如果不存在就会创建一个新的保存起来,对于ICacheManager框架中已经存在一个名为CacheManagerBase的抽象实现了,其内部有一个线程安全的字典用于存放所有的ICache,用于需要继承CacheManagerBase实现自身的CacheManager,只需要实现抽象方法CreateCacheImplementation就行了,最简单的方式就是在方法内部返回一个AbpMemoryCache实例就行了

    /// <summary>
        /// An upper level container for <see cref="ICache"/> objects. 
        /// A cache manager should work as Singleton and track and manage <see cref="ICache"/> objects.
        /// </summary>
        public interface ICacheManager : IDisposable
        {
            /// <summary>
            /// Gets all caches.
            /// </summary>
            /// <returns>List of caches</returns>
            IReadOnlyList<ICache> GetAllCaches();
    
            /// <summary>
            /// Gets (or creates) a cache.
            /// </summary>
            /// <param name="name">Unique name of the cache</param>
            /// <returns>The cache reference</returns>
            ICache GetCache(string name);
        }

      缓存机制中存在一个ICachingConfiguration的配置类,用户可以在自定义的模块中添加ICache的初始化处理逻辑,通常是一个Action<ICache>的委托,添加到配置类的Configurators属性中,每次被创建一个新的ICache对象的时候都会遍历Configurators属性中名称与新建ICache相同,或者无名称的全局性Action<ICache>,用来初始化ICache。

    /// <summary>
        /// Used to configure caching system.
        /// </summary>
        public interface ICachingConfiguration
        {
            /// <summary>
            /// List of all registered configurators.
            /// </summary>
            IReadOnlyList<ICacheConfigurator> Configurators { get; }
    
            /// <summary>
            /// Used to configure all caches.
            /// </summary>
            /// <param name="initAction">
            /// An action to configure caches
            /// This action is called for each cache just after created.
            /// </param>
            void ConfigureAll(Action<ICache> initAction);
    
            /// <summary>
            /// Used to configure a specific cache. 
            /// </summary>
            /// <param name="cacheName">Cache name</param>
            /// <param name="initAction">
            /// An action to configure the cache.
            /// This action is called just after the cache is created.
            /// </param>
            void Configure(string cacheName, Action<ICache> initAction);
        }
    /// <summary>
        /// A registered cache configurator.
        /// </summary>
        public interface ICacheConfigurator
        {
            /// <summary>
            /// Name of the cache.
            /// It will be null if this configurator configures all caches.
            /// </summary>
            string CacheName { get; }
    
            /// <summary>
            /// Configuration action. Called just after the cache is created.
            /// </summary>
            Action<ICache> InitAction { get; }
        }

      另外因为所有数据都是以字符串为Key,值为Object的方式存储的,所以对于一些依赖强类型的使用不太方便,作者也添加了ITypedCache<TKey,TValue>的方式,用于返回强类型的数据,虽然使用方便的,但是ICache所能缓存的对象也有了限制。

      另外在WebApi端的存储,作者新建一个独立的AbpCacheController控制器,新建了几个Clear方法方便用户(通常是系统管理员级别的)通过远程调用WebApi方法的方式来清理缓存,为了安全起见需要提供一个安全验证码的,原生的是在SettingManager中写死一个密码参数和值,只要告诉管理员密码就行了,在访问AbpCacheController的Clear方法的时候提供预先知道的密码就有权限修改了,这个是非常不方便的,所以建议为清理缓存设置一个单独的Permission,并且添加一个AOP(WebApi的ActionFilter或者直接在AbpApiAuthorieAttribute中)根据当前用户的IAbpSession查看是否有权限清理Cache。

      

  • 相关阅读:
    Android集成科大讯飞SDK语音听写及语音合成功能实现
    Android开发中一些常见的问题解决方案
    Android混淆配置文件规范
    android第三方分享之友盟社会化组件
    android一些常用的代码2(收藏)
    svn
    ubuntu 解决中文zip乱码问题
    android优秀Github源码整理
    linux清理内存
    cocos2d-x图层相关 锚点
  • 原文地址:https://www.cnblogs.com/Azula/p/5208179.html
Copyright © 2011-2022 走看看