分类:
2008-11-11 15:57:01
在很多程序里,读取数据的频率比写入要高得多。比如RoadRantz,访问站点来查看帖子的人比张贴帖子的人要多。虽然帖子列表会随着时间不断增长,但其增长速度比不上被查看的速度。
更进一步说,RoadRantz所展示的数据对于实时性要求并不高。如果用户在访问站点时看到了稍微过时一点的帖子列表,并不会产生太多负面影响,他们会稍后再返回站点来查看更新的帖子列表,这样做并不会有太大问题。
尽管如此,DAO每次收到关于帖子列表的请求时,都会访问数据库来获得最新的数据(经常会得到与上次请求一样的数据)。
数据库操作通常都是程序性能的最大瓶颈。对于负载很大的程序来说,针对高度优化的数据源进行的最简单查询都可能会产生性能问题。
均衡考虑数据变化的频率以及查询数据库所付出的性能代价,总是从数据库获取最新数据似乎并不明智,而对频繁访问(但不频繁更新)的数据进行缓存则显得更加合理。
从表面上看,缓存似乎相当简单:在获取一些信息之后,把它保存到本地(和更便于访问的)位置,从而便于下次需要时使用。但是,手工实现缓存是很麻烦的。以HibernateRantDao的getRantsForDay()方法为例:
public List
return hibernateTemplate.loadAll(Rant.class);
}
Spring程序有一种更优雅的缓存解决方案。Spring Modules项目(http://springmodules.dev.java.net)通过切面提供了缓存,它把通知应用于Bean方法来透明地对其结果进行缓存,而不是明确地指定要被缓存的方法。
如图5.13所示,Spring Modules对于缓存的支持涉及到一个代理,它拦截对Spring管理的Bean的一个或多个方法的调用。当一个被代理的方法被调用时,Spring Modules Cache首先查阅一个缓存来判断这个方法是否已经被使用同样参数调用过,如果是,它会返回缓存里的值,实际的方法并不会被调用;否则,实际方法会被调用,其返回值会被保存到缓存里,以备方法下一次被调用时使用。
在这一小节里,我们将使用Spring Modules Cache为RoadRantz的DAO层添加缓存功能,这样会让程序具有更好的性能,让繁忙的数据库轻松一些。
虽然Spring Modules会提供一个代理来拦截方法并把结果保存到缓存,它并没有提供一个实际的缓存解决方案,而是要依赖于第三方的缓存方案。可以使用的方案有多个,包括:
EHCache
GigaSpaces
JBoss Cache
JCS
OpenSymphony的OSCache
Tangosol的Coherence
我们为RoadRantz程序选择EHCache,主要是因为我以前使用它的经验及能够从的Maven仓库轻易获得。无论使用哪个缓存方案,对于Spring Modules Cache的配置基本上都是一样的。
首先要做的是新建一个Spring配置文件来声明缓存。虽然可以把Spring Modules Cache配置放到RoadRantz程序加载的任意一个Spring上下文配置文件里,但最好还是把它们分开,所以我们要创建roadrantz-cache.xml来保存缓存的配置。
与Spring上下文配置文件一样,roadrantz-cache.xml也以
<beans xmlns=""
xmlns:xsi=""
xmlns:ehcache=""
xsi:schemaLocation="
/spring-beans-2.0.xsd
">我们为RoadRantz程序选择的是EHCache,如果想使用其他缓存方案,需要把Spring Modules命名究竟和规划声明修改为相应的内容。表5.6列出了每个命名空间及其URI和规划URI。
表5.6 Spring Modules所支持的缓存方案的命名空间及规划
命名空间 |
命名空间URI |
规划URI |
ehcache |
schema/ehcache |
schema/cache/springmodules- ehcache.xsd |
gigaspaces |
|
schema/cache/springmodules- gigaspaces.xsd |
jboss |
|
schema/cache/springmodules- jboss.xsd |
jcs |
|
schema/cache/springmodules-jcs.xsd |
oscache |
schema/oscache |
schema/cache/springmodules- oscache.xsd |
tangosol |
schema/tangosol |
schema/cache/springmodules- tangosol.xsd |
无论选择哪种缓存,都可以使用一些Spring配置元素在Spring里对缓存进行配置。表5.7列出了这些元素。
表5.7 Spring Modules的配置元素
配 置 元 素 |
用 途 |
|
以Java 5注解来声明被缓存的方法 |
|
以Jakarta通用属性元素数据来声明被缓存的方法 |
|
在Spring XML里配置缓存方案 |
|
在Spring XML里声明一个代理来声明被缓存的方法 |
在使用EHCache作为缓存方案时,需要告诉Spring到哪里寻找EHCache配置文件 ,这正是
在此对configLocation属性的设置告诉Spring从程序类路径的根位置加载EHCache的配置。
配置EHCache
我们已经配置了ehcache.xml文件,如程序清单5.12所示。
程序清单5.12 在ehcache.xml里配置EHCache。
<ehcache>
<defaultCache
maxElementsInMemory="500"
eternal="true"
overflowToDisk="false"
memoryStoreEvictionPolicy="LFU" />
<cache name="rantzCache"
maxElementsInMemory="500"
eternal="true"
overflowToDisk="false"
memoryStoreEvictionPolicy="LFU" />
ehcache>