领先一步
VMware 提供培训和认证,助您加速进步。
了解更多Spring Framework 3.1 M1 中添加的主要功能之一是通用缓存抽象,用于透明地将缓存应用于 Spring 应用程序。就像事务支持一样,缓存抽象允许一致地使用各种缓存解决方案,而对代码的影响最小。
缓存通常用于通过更快的速度(例如从本地内存而不是网络提供数据)透明地提供频繁访问的数据来提高应用程序性能。你们中的许多人已经知道或不知道地使用过缓存:大多数 ORM/JPA 框架都提供专用的缓存功能(也称为二级缓存)。然而,Spring 3.1 M1 引入了一个通用的缓存机制,可以应用于任何 Java 类、方法或库:用户可以将其与现有的缓存基础设施结合使用,为不支持缓存的 API(例如 JDBC)添加缓存,或者仅仅是为了提高缓慢、耗时且资源消耗大的方法的性能。
@Cacheable、@CacheEvict 和 SpEL@Cacheable("books")
public Book findBook(ISBN isbn) {...}
通过用 @Cacheable 注解标记方法,我们告诉容器 findBook 方法由缓存条目 books 支持。也就是说,每次调用该方法时,都会使用方法参数(在本例中是 isbn 参数)作为键执行缓存查找。如果找到值,将返回该值,并跳过方法的执行。但是,如果找不到键,则按常规执行方法,并将其结果存储在缓存中,以便下次调用该方法时,可以在不实际执行(昂贵或缓慢)方法的情况下返回结果。
实际上,并非所有方法只有一个参数,或者更糟糕的是,参数不适合用作缓存键 - 以上述方法的变体为例
public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed)
在这种情况下,可以使用 Spring 3 Spring 表达式语言或 SpEL 来挑选正确的参数,导航对象树
// use property 'rawNumber' on isbn argument as key
@Cacheable(value="book", key="#isbn.rawNumber")
public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed)
或即时计算键,甚至调用任意方法,而无需编写任何代码
// get the key by calling someType#hash(isbn)
@Cacheable(value="book", key="T(someType).hash(#isbn)")
public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed)
此外,还可以指定何时或是否发生缓存:是检查缓存还是完全忽略缓存并正常执行方法。由开发人员决定标准:可以是任何内容,从键的大小或类型到一天中的时间或任意方法的调用结果:SpEL 支持所有这些
// cache only names shorter then 32 chars
@Cacheable(value="book", condition="#name.length < 32")
public Book findBook(String name)
// do not cache on weekends
@Cacheable(value="book", condition="!T(TimeUtils).isWeekend()")
public Book findBook(String name)
缓存抽象还通过 @CacheEvict 注解支持缓存条目或整个缓存的移除。要在一个缓存条目失效时(例如,因为缓存的数据已更新)移除它,可以使用以下方法
// evict all cache entries
@CacheEvict(value = "books", allEntries=true)
public void loadBooks(InputStream batch)
一旦放置了注解,就可以用一行(如果算上 schema 声明,则为三行)“启用”缓存功能
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:cache="http://www.springframework.org/schema/cache"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd">
<cache:annotation-driven />
...
</beans>
与 annotation-driven 元素的其余部分一样,缓存元素在其最简单的形式中使用默认值,但可用于在代理和字节码编织缓存类之间进行选择,或连接所需的缓存实现。
ConcurrentHashMap 的集成,后者非常适合小型、非分布式环境或测试<!-- generic cache manager -->
<bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager">
<property name="caches">
<set>
<bean class="org.springframework.cache.concurrent.ConcurrentCacheFactoryBean" p:name="default"/>
<bean class="org.springframework.cache.concurrent.ConcurrentCacheFactoryBean" p:name="books"/>
</set>
</property>
</bean>
通常,这两种缓存机制可以很好地共存,只要开发人员注意任何域重叠。以 JPA 二级缓存为例,可以在通过 JPA 进行数据访问时使用它,同时在 Web 层或远程服务调用中使用 Spring 缓存。如果适用,可以更进一步,在两种机制之间重用后端缓存。
希望您喜欢这篇关于 Spring 3.1 中新缓存功能的快速入门介绍。有关更多信息,请参阅相关的参考文档 章节和 SPI javadoc。请告诉我们您的想法 - 我们对您的反馈很感兴趣!您可以通过 论坛、博文评论、我们的问题 跟踪器或本人在 Twitter 与我们联系。