对于最新稳定版本,请使用 Spring Framework 7.0.6spring-doc.cadn.net.cn

基于 XML 的声明式缓存

如果无法使用注解(例如由于无法访问源代码或外部代码),你可以使用 XML 进行声明式缓存。因此,与其在方法上添加缓存注解,不如在外部指定目标方法和缓存指令(类似于声明式事务管理的通知)。前一节中的示例可以转换为以下示例:spring-doc.cadn.net.cn

<!-- the service we want to make cacheable -->
<bean id="bookService" class="x.y.service.DefaultBookService"/>

<!-- cache definitions -->
<cache:advice id="cacheAdvice" cache-manager="cacheManager">
	<cache:caching cache="books">
		<cache:cacheable method="findBook" key="#isbn"/>
		<cache:cache-evict method="loadBooks" all-entries="true"/>
	</cache:caching>
</cache:advice>

<!-- apply the cacheable behavior to all BookService interfaces -->
<aop:config>
	<aop:advisor advice-ref="cacheAdvice" pointcut="execution(* x.y.BookService.*(..))"/>
</aop:config>

<!-- cache manager definition omitted -->

在上述配置中,bookService 被设置为可缓存的。要应用的缓存语义封装在 cache:advice 定义中,该定义使得 findBooks 方法用于将数据放入缓存,而 loadBooks 方法用于从缓存中移除数据。这两个定义都作用于名为 books 的缓存。spring-doc.cadn.net.cn

aop:config 定义通过使用 AspectJ 切点表达式,将缓存通知(advice)应用到程序中的相应位置(更多信息请参见Spring 中的面向切面编程)。在上述示例中,BookService 中的所有方法都会被考虑,并对其应用缓存通知。spring-doc.cadn.net.cn

声明式的 XML 缓存支持所有基于注解的模型,因此在这两种方式之间切换应该相当容易。此外,二者可以在同一个应用程序中同时使用。 基于 XML 的方法不会触及目标代码。然而,它本质上更为冗长。当处理包含重载方法且这些方法需要被缓存的类时,由于 method 参数不是一个良好的区分依据,因此要准确识别合适的方法就需要额外的工作量。在这种情况下,您可以使用 AspectJ 切点来精确选择目标方法,并应用相应的缓存功能。 不过,通过 XML 配置,更容易在包、组或接口范围内应用缓存(同样得益于 AspectJ 切点),也更容易创建类似模板的定义(正如我们在前面的示例中通过 cache:definitionscache 属性来定义目标缓存那样)。spring-doc.cadn.net.cn