- 作者简介
- 内容提要
- 关于本书
- 路线图
- 代码规范与下载
- 作者在线
- 封面插图简介
- 前言
- 译者序
- 致谢
- 第1部分 Spring 的核心
- 第1章 Spring 之旅
- 第2章 装配 Bean
- 第3章 高级装配
- 第4章 面向切面的 Spring
- 第2部分 Web 中的 Spring
- 第5章 构建 Spring Web 应用程序
- 第6章 渲染 Web 视图
- 第7章 Spring MVC 的高级技术
- 第8章 使用 Spring Web Flow
- 第9章 保护 Web 应用
- 第3部分 后端中的 Spring
- 第10章 通过 Spring 和 JDBC 征服数据库
- 第11章 使用对象-关系映射持久化数据
- 第12章 使用 NoSQL 数据库
- 第13章 缓存数据
- 第14章 保护方法应用
- 第4部分 Spring 集成
- 第15章 使用远程服务
- 第16章 使用 Spring MVC 创建 REST API
- 第17章 Spring消息
- 第18章 使用 WebSocket 和 STOMP 实现消息功能
- 第19章 使用 Spring 发送 Email
- 第20章 使用 JMX 管理 Spring Bean
- 第21章 借助 Spring Boot 简化 Spring 开发
13.3 使用XML声明缓存
你可能想要知道为什么想要以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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论