zoukankan      html  css  js  c++  java
  • (理论篇)petshop中缓存运用之我见

    petshop中关于缓存的应用很广泛,这里主要是剖析一下实现:

    1 先从cs页面开始看起,见代码:

    namespace PetShop.Web {
        
        public partial class Products : System.Web.UI.Page {
    
            protected void Page_Load(object sender, EventArgs e) {
                //get page header and title
                Page.Title = WebUtility.GetCategoryName(Request.QueryString["categoryId"]);
            }
        }
    }
    
    WebUtility.GetCategoryName此方法根据商品id取得商品名称,此名称是有缓存的

    2 来看WebUtility这个通用类里的实现

     public static string GetCategoryName(string categoryId) {
    
                Category category = new Category();
                if (!enableCaching)
                    return category.GetCategory(categoryId).Name;
    
                string cacheKey = string.Format(CATEGORY_NAME_KEY, categoryId);
    
                string data = (string)HttpRuntime.Cache[cacheKey];
                if (data == null) {
                    int cacheDuration = int.Parse(ConfigurationManager.AppSettings["CategoryCacheDuration"]);
    
                    data = category.GetCategory(categoryId).Name;
    
                    AggregateCacheDependency cd = DependencyFacade.GetCategoryDependency();
    
                    HttpRuntime.Cache.Add(cacheKey, data, cd, DateTime.Now.AddHours(cacheDuration), Cache.NoSlidingExpiration, CacheItemPriority.High, null);
                }
    
                return data;
            }
    
    这里的实现很简单,判断缓存是否存在,存在直接返回数据,不存在,则将数据缓存起来,并设置了缓存依赖
    
    (缓存依赖的作用在于数据表更新时,缓存的数据也会自动更新)

    3 来看缓存依赖的实现,主要是这一句代码

    AggregateCacheDependency cd = DependencyFacade.GetCategoryDependency();
    
    意思是取得缓存依赖,如下:
    
    namespace PetShop.CacheDependencyFactory {
        public static class DependencyFacade {
            private static readonly string path = ConfigurationManager.AppSettings["CacheDependencyAssembly"];
    
            public static AggregateCacheDependency GetCategoryDependency() {
                if (!string.IsNullOrEmpty(path))
                    return DependencyAccess.CreateCategoryDependency().GetDependency();
                else
                    return null;
            }
    
            public static AggregateCacheDependency GetProductDependency() {
                if (!string.IsNullOrEmpty(path))
                    return DependencyAccess.CreateProductDependency().GetDependency();
                else
                    return null;
            }
    
            public static AggregateCacheDependency GetItemDependency() {
                if (!string.IsNullOrEmpty(path))
                    return DependencyAccess.CreateItemDependency().GetDependency();
                else
                    return null;
            }
        }
    }
    
    读取 <add key="CacheDependencyAssembly" value="PetShop.TableCacheDependency"/>中的配置,若有配置,则通过
    
    DependencyAccess.CreateItemDependency().GetDependency();来获取

    4 来看DependencyAccess.CreateItemDependency().GetDependency();的实现

    namespace PetShop.CacheDependencyFactory {
        public static class DependencyAccess {
            public static IPetShopCacheDependency CreateCategoryDependency() {
                return LoadInstance("Category");
            }
    
            public static IPetShopCacheDependency CreateProductDependency() {
                return LoadInstance("Product");
            }
    
            public static IPetShopCacheDependency CreateItemDependency() {
                return LoadInstance("Item");
            }
    
            private static IPetShopCacheDependency LoadInstance(string className) {
    
                string path = ConfigurationManager.AppSettings["CacheDependencyAssembly"];
                string fullyQualifiedClass = path + "." + className;
    
                // Using the evidence given in the config file load the appropriate assembly and class
                return (IPetShopCacheDependency)Assembly.Load(path).CreateInstance(fullyQualifiedClass);
            }
        }

    这里应用到了反射和配置文件相结合的方式,读取应用程序集的配置

     <add key="CacheDependencyAssembly" value="PetShop.TableCacheDependency"/>,

    通过反射得到具体类的实例

    5 具体反射的缓存实例如下:

    namespace PetShop.TableCacheDependency {
        public class Product : TableDependency {
    
            public Product() : base("ProductTableDependency") { }
        }
    }

    调用的是父类TableDependency的构造方法来实例化

    6 这里才是具体的缓存依赖值,目的就是为具体数据库的具体哪几张表设置缓存依赖,

    即这几张表的数据发生变化时,缓存的相应数据也会自动更新过来,优势在此

    namespace PetShop.TableCacheDependency {
    
        public abstract class TableDependency : PetShop.ICacheDependency.IPetShopCacheDependency {
    
            // This is the separator that's used in web.config
            protected char[] configurationSeparator = new char[] { ',' };
    
            protected AggregateCacheDependency dependency = new AggregateCacheDependency();
    
            protected TableDependency(string configKey) {
    
                string dbName = ConfigurationManager.AppSettings["CacheDatabaseName"];
                string tableConfig = ConfigurationManager.AppSettings[configKey];
                string[] tables = tableConfig.Split(configurationSeparator);
    
                foreach (string tableName in tables)
                    dependency.Add(new SqlCacheDependency(dbName, tableName));
            }
    
            public AggregateCacheDependency GetDependency() {
                return dependency;
            }
        }

    配置需要设置缓存的数据库,和需要缓存的表

    <add key="CacheDatabaseName" value="MSPetShop4"/>
      <!-- *TableDependency lists table dependency for each instance separated by comma -->
      <add key="CategoryTableDependency" value="Category"/>
      <add key="ProductTableDependency" value="Product,Category"/>
      <add key="ItemTableDependency" value="Product,Category,Item"/>

    7 以上既是缓存的实现,和缓存依赖的具体实现,记下供以后在项目中使用!

  • 相关阅读:
    ASP.NET Core 3.0 迁移避坑指南
    Go初学乍练
    IdentityServer4 常见问题
    ASP.NET Core 奇淫技巧之动态WebApi
    Visual Studio 2019 16.1 使用 .NET Core 3.0
    【Java】maven多项目资源共享
    【Web】Web开发中的异常处理方案
    【UML】Java代码与UML模型相互转换方法
    【Spark】为什么没有任务调度到新增的Worker之上???
    【网络】高性能网络编程--下一个10年,是时候考虑C10M并发问题了
  • 原文地址:https://www.cnblogs.com/jangwewe/p/2985091.html
Copyright © 2011-2022 走看看