返回介绍

13.3 使用XML声明缓存

发布于 2024-08-17 00:45:49 字数 4060 浏览 0 评论 0 收藏 0

你可能想要知道为什么想要以XML的方式声明缓存。毕竟,本章中我们所看到的缓存注解要优雅得多。

我认为有两个原因:

你可能会觉得在自己的源码中添加Spring的注解有点不太舒服;

你需要在没有源码的bean上应用缓存功能。

在上面的任意一种情况下,最好(或者说需要)将缓存配置与缓存数据的代码分隔开来。Spring的cache命名空间提供了使用XML声明缓存规则的方法,可以作为面向注解缓存的替代方案。因为缓存是一种面向切面的行为,所以cache命名空间会与Spring的aop命名空间结合起来使用,用来声明缓存所应用的切点在哪里。

要开始配置XML声明的缓存,首先需要创建Spring配置文件,这个文件中要包含cache和aop命名空间:

cache命名空间定义了在Spring XML配置文件中声明缓存的配置元素。表13.5列出了cache命名空间所提供的所有元素。

表13.5 Spring的cache命名空间提供了以XML方式配置缓存规则的元素

元素

描述

<cache:annotation-driven>

启用注解驱动的缓存。等同于Java配置中的@EnableCaching

<cache:advice>

定义缓存通知(advice)。结合<aop:advisor>,将通知应用到切点上

<cache:caching>

在缓存通知中,定义一组特定的缓存规则

<cache:cacheable>

指明某个方法要进行缓存。等同于@Cacheable注解

<cache:cache-put>

指明某个方法要填充缓存,但不会考虑缓存中是否已有匹配的值。等同于@CachePut注解

<cache:cache-evict>

指明某个方法要从缓存中移除一个或多个条目,等同于@CacheEvict注解

<cache:annotation-driven>元素与Java配置中所对应的@EnableCaching非常类似,会启用注解驱动的缓存。我们已经讨论过这种风格的缓存,因此没有必要再对其进行介绍。

表13.5中其他的元素都用于基于XML的缓存配置。接下来的代码清单展现了如何使用这些元素为SpittleRepositorybean配置缓存,其作用等同于本章前面章使用缓存注解的方式。

程序清单13.7 使用XML元素为SpittleRepository声明缓存规则

在程序清单13.7中,我们首先看到的是<aop:advisor>,它引用ID为cacheAdvice的通知,该元素将这个通知与一个切点进行匹配,因此建立了一个完整的切面。在本例中,这个切面的切点会在执行SpittleRepository的任意方法时触发。如果这样的方法被Spring应用上下文中的任意某个bean所调用,那么就会调用切面的通知。

在这里,通知利用<cache:advice>元素进行了声明。在<cache:advice>元素中,可以包含任意数量的<cache:caching>元素,这些元素用来完整地定义应用的缓存规则。在本例中,只包含了一个<cache:caching>元素。这个元素又包含了三个<cache:cacheable>元素和一个<cache:cache-put>元素。

每个<cache:cacheable>元素都声明了切点中的某一个方法是支持缓存的。这是与@Cacheable注解同等作用的XML元素。具体来讲,findRecent()、findOne()和findBySpitterId()都声明为支持缓存,它们的返回值将会保存在名为spittleCache的缓存之中。

<cache:cache-put>是Spring XML中与@CachePut注解同等作用的元素。它表明一个方法的返回值要填充到缓存之中,但是这个方法本身并不会从缓存中获取返回值。在本例中,save()方法用来填充缓存。同面向注解的缓存一样,我们需要将默认的key改为返回Spittle对象的id属性。

最后,<cache:cache-evict>元素是Spring XML中用来替代@CacheEvict注解的。它会从缓存中移除元素,这样的话,下次有人进行查找的时候就找不到了。在这里,调用remove()时,会将缓存中的Spittle删除掉,其中key与remove()方法所传递进来的ID参数相等的条目会从缓存中移除。

需要注意的是,<cache:advice>元素有一个cache-manager元素,用来指定作为缓存管理器的bean。它的默认值是cacheManager,这与程序清单13.7底部的<bean>声明恰好是一致的,所以没有必要再显式地进行设置。但是,如果缓存管理器的ID与之不同的话(使用多个缓存管理器的时候,可能会遇到这样的场景),那么可以通过设置cache-manager属性指定要使用哪个缓存管理器。

另外,还要留意的是,<cache:cacheable>、<cache:cache-put>和<cache:cache-evict>元素都引用了同一个名为spittleCache的缓存。为了消除这种重复,我们可以在<cache:caching>元素上指明缓存的名字:

<cache:caching>有几个可以供<cache:cacheable>、<cache:cache-put>和<cache:cache-evict>共享的属性,包括:

cache:指明要存储和获取值的缓存;

condition:SpEL表达式,如果计算得到的值为false,将会为这个方法禁用缓存;

key:SpEL表达式,用来得到缓存的key(默认为方法的参数);

method:要缓存的方法名。

除此之外,<cache:cacheable>和<cache:cache-put>还有一个unless属性,可以为这个可选的属性指定一个SpEL表达式,如果这个表达式的计算结果为true,那么将会阻止将返回值放到缓存之中。

<cache:cache-evict>元素还有几个特有的属性:

all-entries:如果是true的话,缓存中所有的条目都会被移除掉。如果是false的话,只有匹配key的条目才会被移除掉。

before-invocation:如果是true的话,缓存条目将会在方法调用之前被移除掉。如果是false的话,方法调用之后才会移除缓存。

all-entries和before-invocation的默认值都是false。这意味着在使用<cache:cache-evict>元素且不配置这两个属性时,会在方法调用完成后只删除一个缓存条目。要删除的条目会通过默认的key(基于方法的参数)进行识别,当然也可以通过为名为key的属性设置一个SpEL表达式指定要删除的key。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文