Declarative XML-based Caching
如果注释不是一种选择(可能是因为无法访问源或外部代码),您可以使用 XML 进行声明性缓存。因此,您可以指定目标方法和外部缓存指令(类似于声明性事务管理advice),而无需为缓存注释方法。上一节的示例可以转换为以下示例:
If annotations are not an option (perhaps due to having no access to the sources or no external code), you can use XML for declarative caching. So, instead of annotating the methods for caching, you can specify the target method and the caching directives externally (similar to the declarative transaction management advice). The example from the previous section can be translated into the following example:
<!-- 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
缓存进行操作。
In the preceding configuration, the bookService
is made cacheable. The caching semantics
to apply are encapsulated in the cache:advice
definition, which causes the findBooks
method to be used for putting data into the cache and the loadBooks
method for evicting
data. Both definitions work against the books
cache.
通过使用 AspectJ 切点表达式(更多信息可在Aspect Oriented Programming with Spring中找到),`aop:config`定义将缓存建议应用到程序中的适当点。在前面的示例中,将会考虑 `BookService`中的所有方法并将缓存建议应用于它们。
The aop:config
definition applies the cache advice to the appropriate points in the
program by using the AspectJ pointcut expression (more information is available in
Aspect Oriented Programming with Spring). In the preceding example,
all methods from the BookService
are considered and the cache advice is applied to them.
声明性 XML 缓存支持所有基于注释的模型,因此在两者之间移动应该相当容易。此外,两者都可以用在同一个应用程序中。基于 XML 的方法不会影响目标代码。但是,它本质上更加冗长。在处理针对缓存的超载方法的类时,识别正确的方法需要额外的努力,因为 method
参数不是一个好鉴别器。在这些情况下,您可以使用 AspectJ 切入点来选择目标方法并应用适当的缓存功能。但是,通过 XML,可以更容易地应用包或组或接口范围的缓存(同样,由于 AspectJ 切入点),并创建类似模板的定义(就像我们在前面的示例中通过 cache:definitions``cache
属性定义目标缓存所做的那样)。
The declarative XML caching supports all of the annotation-based model, so moving between
the two should be fairly easy. Furthermore, both can be used inside the same application.
The XML-based approach does not touch the target code. However, it is inherently more
verbose. When dealing with classes that have overloaded methods that are targeted for
caching, identifying the proper methods does take an extra effort, since the method
argument is not a good discriminator. In these cases, you can use the AspectJ pointcut
to cherry pick the target methods and apply the appropriate caching functionality.
However, through XML, it is easier to apply package or group or interface-wide caching
(again, due to the AspectJ pointcut) and to create template-like definitions (as we did
in the preceding example by defining the target cache through the cache:definitions
cache
attribute).