我心中的核心组件(可插拔的AOP)~第二回 缓存拦截器

简介:

AOP面向切面的编程,也称面向方面的编程,我更青睐于前面的叫法,将一个大系统切成多个独立的部分,而这个独立的部分又可以方便的插拔在其它领域的系统之中,这种编程的方式我们叫它面向切面,而这些独立的部分,我们很早之前叫它部件,在SOA里,它叫做服务,而我认为叫它模块更加贴切,确实,这些与领域无关的东西,是像是一个个的功能模块。

之前讲过一个日志组件,有兴趣的同学可以查看:第一回 日志记录组件

今天主要说一下缓存组件,就是缓存模块,这些模块可以很方便的为每个方法添加缓存机制,事实上是在方法体执行之前,进行缓存对象的检索,当检索到有缓存,就直接加载缓存对象了,这对于数据高并发情况下,尤其有用,呵呵。

实现缓存的武器:Microsoft.Practices.EnterpriseLibrary.Caching

辅助兵器(IOC):Microsoft.Practices.Unity

实现的效果:根据在配置文件中对要缓存的部分进行配置后,使它减少对数据库的交互,提高程序的相应能力

下面开始我们的Caching之旅

1 使用nuget添加caching和Unity组件,添加好了之后在引用中自己出现

在package.config中有我们的组件的相关说明

<packages> 
  <package id="Unity" version="3.0.1304.0" targetFramework="net45" />
  <package id="Unity.Interception" version="3.0.1304.0" targetFramework="net45" />
  <package id="EnterpriseLibrary.Caching" version="5.0.505.0" targetFramework="net45" />
  <package id="EnterpriseLibrary.Common" version="5.0.505.0" targetFramework="net45" />
  <package id="CommonServiceLocator" version="1.0" targetFramework="net45" />
</packages>

2 在web.config添加相应的unity注入信息和拦截信息的配置

<configSections>
    <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
    <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration" />
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
    <section name="cachingConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Caching.Configuration.CacheManagerSettings, Microsoft.Practices.EnterpriseLibrary.Caching, Version=5.0.505.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
  </configSections>
<unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
    <sectionExtension type="Microsoft.Practices.Unity.InterceptionExtension.Configuration.InterceptionConfigurationExtension, Microsoft.Practices.Unity.Interception.Configuration" />
    <container>
      <extension type="Interception" />
      <register type="Infrastructure.Caching.ICacheProvider,  DDD_AOP_WCF" mapTo="Infrastructure.Caching.EntLibCacheProvider,  DDD_AOP_WCF" />
      <!--Repository Context & Repositories-->

      <register type="DDD_AOP_WCF.Repository.IProductRepository, DDD_AOP_WCF" mapTo="DDD_AOP_WCF.Repository.ProductRepository, DDD_AOP_WCF">
       <!--  <interceptor type="VirtualMethodInterceptor" />-->
        <interceptor type="InterfaceInterceptor"/>
        <interceptionBehavior type="Infrastructure.InterceptionBehaviors.CachingBehavior,DDD_AOP_WCF" />
        <interceptionBehavior type="Infrastructure.InterceptionBehaviors.ExceptionLoggingBehavior, DDD_AOP_WCF" />
      </register>
    </container>
  </unity>

下面是缓存组件的配置:

  <!--BEGIN: Caching-->
  <cachingConfiguration defaultCacheManager="ByteartRetailCacheManager">
    <cacheManagers>
      <add name="ByteartRetailCacheManager" type="Microsoft.Practices.EnterpriseLibrary.Caching.CacheManager, Microsoft.Practices.EnterpriseLibrary.Caching, Version=5.0.505.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
          expirationPollFrequencyInSeconds="600" maximumElementsInCacheBeforeScavenging="1000"
          numberToRemoveWhenScavenging="10" backingStoreName="NullBackingStore" />
    </cacheManagers>
    <backingStores>
      <add type="Microsoft.Practices.EnterpriseLibrary.Caching.BackingStoreImplementations.NullBackingStore, Microsoft.Practices.EnterpriseLibrary.Caching, Version=5.0.505.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
          name="NullBackingStore" />
    </backingStores>
  </cachingConfiguration>
  <!--END: Caching-->

3 建立一个测试用的IRepository接口和一个个性化操作的接口IProductRepository

  public interface IRepository<TEntity> where TEntity : class
    {
        void Insert(TEntity entity);
        string Hello();
        IQueryable<TEntity> GetEntities();
    }
  public interface IProductRepository : IRepository<Product>
    {
        /// <summary>
        /// 获取产品列表
        /// </summary>
        /// <returns></returns>
        [Caching(CachingMethod.Get)]
        List<Product> GetProduct();

        /// <summary>
        /// 建立产品
        /// </summary>
        [Caching(CachingMethod.Remove, "GetProduct")]
        void AddProduct(Product entity);

        /// <summary>
        /// 修改产品
        /// </summary>
        [Caching(CachingMethod.Remove, "GetProduct")]
        void ModifyProduct(Product entity);

    }

对这个接口进行实现,当然,它可以有多个实现版本,这也是IoC出现的原因

4 建立一个本地服务器,它是与IoC实现松耦合的前提,而IoC是我们实现程序代码松耦合的前提,呵呵。

  View Code

5 建立一个缓存拦截器,它是与具体领域没有关系的,我们的拦截器Interception,可以有两个,如缓存拦截,日志拦截,异常拦截等等,我会在后面的文章中进

行介绍

  View Code

6 下面是前台程序的调用方法

   IProductRepository productRepository = ServiceLocator.Instance.GetService<IProductRepository>();
   ViewBag.Product = productRepository.GetProduct();
@{var Model = ViewBag.Product as List<学习陈晴阳的DDD_AOP_WCF.Product>; }
@if (Model != null && Model.Count > 0)
{
    foreach (var item in Model)
    {
    <p>@item.ProductName</p>
    }
}

好了,当我们为程序加上缓存拦截器之后,当它的数据没有发生变化时,会直接从缓存中读取对象,而不会与数据库发生访问!

本文转自博客园张占岭(仓储大叔)的博客,原文链接:我心中的核心组件(可插拔的AOP)~第二回 缓存拦截器,如需转载请自行联系原博主。

目录
相关文章
|
6天前
|
存储 缓存 JavaScript
缓存组件状态,提升用户体验:探索 keep-alive 的神奇世界
缓存组件状态,提升用户体验:探索 keep-alive 的神奇世界
缓存组件状态,提升用户体验:探索 keep-alive 的神奇世界
|
6天前
|
Java Spring
Spring 源码阅读 72:基于 CGLIB 的 AOP 代理的原理(2)- 拦截器的查找与执行
【1月更文挑战第7天】本文分析了基于 CGLIB 的 AOP 代理如何查找和执行拦截器链,其主要的逻辑在 DynamicAdvisedInterceptor 的intercept方法执行。
37 1
|
6天前
|
缓存 Java Spring
Spring 源码阅读 66:基于 JDK 的 AOP 代理如何获取拦截器链(4)- 将 Advice 封装为拦截器
【1月更文挑战第1天】本文分析了 Advice 被封装成 MethodInterceptor 的过程,Spring AOP 用到的五种 Advice 中,有些本身就是 MethodInterceptor 的实现类,而有些需要通过适配器的封装。
44 0
|
6天前
|
缓存 JavaScript 网络架构
Vue.js 进阶技巧:keep-alive 缓存组件解析
Vue.js 进阶技巧:keep-alive 缓存组件解析
|
6天前
|
缓存 JavaScript 前端开发
掌握组件缓存:解开Vue.js中<keep-alive>的奥秘
掌握组件缓存:解开Vue.js中<keep-alive>的奥秘
|
6天前
|
缓存 JavaScript
keep-alive 是 Vue 内置的一个组件,被用来缓存组件实例。
keep-alive 是 Vue 内置的一个组件,被用来缓存组件实例。
|
6天前
|
XML Java 数据格式
Spring 源码阅读 70:基于 JDK 的 AOP 代理拦截器链执行(4)- 容易被忽略的 ExposeInvocationInterceptor
【1月更文挑战第5天】本文分析了 Spring AOP 拦截器链中的一个特殊拦截器 ExposeInvocationInterceptor 的注册的时机以及它的作用。至此,基于 JDK 的 AOP 代理拦截器链执行的逻辑就分析完了。
455 0
|
6天前
|
Java 索引 Spring
Spring 源码阅读 69:基于 JDK 的 AOP 代理拦截器链执行(3)- MethodInterceptor 分析
【1月更文挑战第4天】本文详细分析了 Spring AOP 中五种增强类型对应的拦截器中增强方法的执行逻辑,结合上一篇中分析的 ReflectiveMethodInvocation 中proceed方法的执行逻辑,就组成了完整的拦截器链递归调用的逻辑。
35 0
|
6天前
|
Java 索引 Spring
Spring 源码阅读 68:基于 JDK 的 AOP 代理拦截器链执行(2)- ReflectiveMethodInvocation 分析
【1月更文挑战第3天】本文分析了 ReflectiveMethodInvocation 类中的proceed方法,通过对这个方法的分析,了解了连接器链中的增强逻辑是如何逐层执行的,以及目标方法是什么时候被调用的。
44 0
|
6天前
|
Java Spring
Spring 源码阅读 67:基于 JDK 的 AOP 代理拦截器链执行(1)- 执行前的准备工作
【1月更文挑战第2天】本文总结了 JdkDynamicAopProxy 的invoke方法在获取到拦截器链之后,是如何开始执行增强逻辑的。对于拦截器链为空的情况,会直接调用目标方法,而存在拦截器的情况下,会将拦截器链和目标方法调用的信息封装成一个 MethodInterceptor 对象,执行其proceed方法,来完成增强逻辑和目标方法的执行。
24 0