spring缓存

来源:互联网 发布:网络摄像机 编辑:程序博客网 时间:2024/05/16 01:53

5.7  缓存

在很多程序里,读取数据的频率比写入要高得多。比如RoadRantz,访问站点来查看帖子的人比张贴帖子的人要多。虽然帖子列表会随着时间不断增长,但其增长速度比不上被查看的速度。

更进一步说,RoadRantz所展示的数据对于实时性要求并不高。如果用户在访问站点时看到了稍微过时一点的帖子列表,并不会产生太多负面影响,他们会稍后再返回站点来查看更新的帖子列表,这样做并不会有太大问题。

尽管如此,DAO每次收到关于帖子列表的请求时,都会访问数据库来获得最新的数据(经常会得到与上次请求一样的数据)。


数据库操作通常都是程序性能的最大瓶颈。对于负载很大的程序来说,针对高度优化的数据源进行的最简单查询都可能会产生性能问题。


均衡考虑数据变化的频率以及查询数据库所付出的性能代价,总是从数据库获取最新数据似乎并不明智,而对频繁访问(但不频繁更新)的数据进行缓存则显得更加合理。

从表面上看,缓存似乎相当简单:在获取一些信息之后,把它保存到本地(和更便于访问的)位置,从而便于下次需要时使用。但是,手工实现缓存是很麻烦的。以HibernateRantDao的getRantsForDay()方法为例:

   

这个方法就非常适合缓存。我们不可能让时间倒转,到过去的某一天来添加帖子。只要被查询的不是今天,对其他任意一天进行查询而返回的帖子列表都是一样的,也就没有必要总是对数据库进行操作来返回过去某一天的帖子列表。我们只需查询数据库一次,然后就可以记住结果,以备下次查询时使用。

下面我们来修改getRantsForDay(),使用某种自制形式的缓存:


     

这个版本的getRantsForDay()很不好用。这个方法的实际作用是查询指定日期的帖子,但其中大量代码都被用于处理缓存了。而且,它还没有直接处理缓存的一些复杂情况,比如缓存过期、刷新或溢出。

幸运的是,Spring程序有一种更优雅的缓存解决方案。Spring Modules项目(http://springmodules.dev.java.net)通过切面提供了缓存,它把通知应用于Bean方法来透明地对其结果进行缓存,而不是明确地指定要被缓存的方法。

如图5.13所示,Spring Modules对于缓存的支持涉及到一个代理,它拦截对Spring管理的Bean的一个或多个方法的调用。当一个被代理的方法被调用时,Spring Modules Cache首先查阅一个缓存来判断这个方法是否已经被使用同样参数调用过,如果是,它会返回缓存里的值,实际的方法并不会被调用;否则,实际方法会被调用,其返回值会被保存到缓存里,以备方法下一次被调用时使用。

  图5.13 Spring Module缓存模块拦截对bean方法
的调用,从缓存获取数据来实现快速数据访问,
以此减少对数据库的实际访问。在这一小节里,我们将使用Spring Modules Cache为RoadRantz的DAO层添加缓存功能,这样会让程序具有更好的性能,让繁忙的数据库轻松一些。
原创粉丝点击